From ea5900c612503fbbcd7d24bb3ca6ebe8e57312a1 Mon Sep 17 00:00:00 2001 From: Fredrik Johansson Date: Sun, 13 Aug 2023 12:58:23 +0200 Subject: [PATCH] gr_mat_mul_strassen; nmod32 gr domain --- doc/source/gr_domains.rst | 4 +- doc/source/gr_mat.rst | 1 + doc/source/history.rst | 2 +- src/gr.h | 4 +- src/gr/init_random.c | 2 + src/gr/nmod32.c | 459 +++++++++++++++++++++++++++++++ src/gr/nmod8.c | 60 +++- src/gr/test/t-nmod32.c | 39 +++ src/gr_mat.h | 1 + src/gr_mat/mul_strassen.c | 176 ++++++++++++ src/gr_mat/test/t-mul_strassen.c | 80 ++++++ 11 files changed, 811 insertions(+), 17 deletions(-) create mode 100644 src/gr/nmod32.c create mode 100644 src/gr/test/t-nmod32.c create mode 100644 src/gr_mat/mul_strassen.c create mode 100644 src/gr_mat/test/t-mul_strassen.c diff --git a/doc/source/gr_domains.rst b/doc/source/gr_domains.rst index f6a5efe02e..767e3c5088 100644 --- a/doc/source/gr_domains.rst +++ b/doc/source/gr_domains.rst @@ -100,10 +100,12 @@ Base rings and fields `\mathbb{Z}[i]` with elements of type :type:`fmpzi_t`. .. function:: void gr_ctx_init_nmod8(gr_ctx_t ctx, unsigned char n) + void gr_ctx_init_nmod32(gr_ctx_t ctx, unsigned int n) Initializes *ctx* to the ring `\mathbb{Z}/n\mathbb{Z}` of integers modulo *n* where - elements have type :type:`uint8`. We require `1 \le n \le 255`. + elements have type :type:`uint8` or :type:`uint32`. The modulus must be + nonzero. .. function:: void gr_ctx_init_nmod(gr_ctx_t ctx, ulong n) diff --git a/doc/source/gr_mat.rst b/doc/source/gr_mat.rst index acb9a70299..6e0d1270c0 100644 --- a/doc/source/gr_mat.rst +++ b/doc/source/gr_mat.rst @@ -224,6 +224,7 @@ Arithmetic .. function:: int gr_mat_sub(gr_mat_t res, const gr_mat_t mat1, const gr_mat_t mat2, gr_ctx_t ctx) .. function:: int gr_mat_mul_classical(gr_mat_t res, const gr_mat_t mat1, const gr_mat_t mat2, gr_ctx_t ctx) + int gr_mat_mul_strassen(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, gr_ctx_t ctx); int gr_mat_mul_generic(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, gr_ctx_t ctx) int gr_mat_mul(gr_mat_t res, const gr_mat_t mat1, const gr_mat_t mat2, gr_ctx_t ctx) diff --git a/doc/source/history.rst b/doc/source/history.rst index eb69983d9a..842f0051eb 100644 --- a/doc/source/history.rst +++ b/doc/source/history.rst @@ -182,7 +182,7 @@ List of additions * ``fmpz_ui_pow_ui`` * ``fmpzi_set_qqbar`` * ``get_default_mpn_ctx`` -* ``gr_abs, gr_acos, gr_acos_pi, gr_acosh, gr_acot, gr_acot_pi, gr_acoth, gr_acsc, gr_acsc_pi, gr_acsch, gr_add, gr_add_fmpq, gr_add_fmpz, gr_add_other, gr_add_si, gr_add_ui, gr_addmul, gr_addmul_fmpq, gr_addmul_fmpz, gr_addmul_other, gr_addmul_si, gr_addmul_ui, gr_agm, gr_agm1, gr_airy, gr_airy_ai, gr_airy_ai_prime, gr_airy_ai_prime_zero, gr_airy_ai_zero, gr_airy_bi, gr_airy_bi_prime, gr_airy_bi_prime_zero, gr_airy_bi_zero, gr_asec, gr_asec_pi, gr_asech, gr_asin, gr_asin_pi, gr_asinh, gr_atan, gr_atan2, gr_atan_pi, gr_atanh, gr_barnes_g, gr_bellnum_fmpz, gr_bellnum_ui, gr_bellnum_vec, gr_bernoulli_fmpz, gr_bernoulli_ui, gr_bernoulli_vec, gr_bernpoly_ui, gr_bessel_i, gr_bessel_i_scaled, gr_bessel_j, gr_bessel_j_y, gr_bessel_k, gr_bessel_k_scaled, gr_bessel_y, gr_beta, gr_beta_lower, gr_bin, gr_bin_ui, gr_bin_ui_vec, gr_bin_uiui, gr_bin_vec, gr_carlson_rc, gr_carlson_rd, gr_carlson_rf, gr_carlson_rg, gr_carlson_rj, gr_catalan, gr_ceil, gr_chebyshev_t, gr_chebyshev_t_fmpz, gr_chebyshev_u, gr_chebyshev_u_fmpz, gr_clear, gr_cmp, gr_cmp_other, gr_cmpabs, gr_cmpabs_other, gr_conj, gr_cos, gr_cos_integral, gr_cos_pi, gr_cosh, gr_cosh_integral, gr_cot, gr_cot_pi, gr_coth, gr_coulomb, gr_coulomb_f, gr_coulomb_g, gr_coulomb_hneg, gr_coulomb_hpos, gr_csc, gr_csc_pi, gr_csch, gr_csgn, gr_ctx_ca_get_option, gr_ctx_ca_set_option, gr_ctx_clear, gr_ctx_cmp_coercion, gr_ctx_data_as_ptr, gr_ctx_data_ptr, gr_ctx_fmpz_mod_set_primality, gr_ctx_fq_degree, gr_ctx_fq_order, gr_ctx_fq_prime, gr_ctx_get_real_prec, gr_ctx_get_str, gr_ctx_has_real_prec, gr_ctx_init_complex_acb, gr_ctx_init_complex_algebraic_ca, gr_ctx_init_complex_ca, gr_ctx_init_complex_float_acf, gr_ctx_init_complex_qqbar, gr_ctx_init_dirichlet_group, gr_ctx_init_fmpq, gr_ctx_init_fmpz, gr_ctx_init_fmpz_mod, gr_ctx_init_fmpz_poly, gr_ctx_init_fmpzi, gr_ctx_init_fq, gr_ctx_init_fq_nmod, gr_ctx_init_fq_zech, gr_ctx_init_gr_series, gr_ctx_init_gr_series_mod, gr_ctx_init_matrix_domain, gr_ctx_init_matrix_ring, gr_ctx_init_matrix_space, gr_ctx_init_gr_mpoly, gr_ctx_init_nf, gr_ctx_init_nf_fmpq_poly, gr_ctx_init_nmod, gr_ctx_init_nmod8, gr_ctx_init_perm, gr_ctx_init_gr_poly, gr_ctx_init_psl2z, gr_ctx_init_random, gr_ctx_init_real_algebraic_ca, gr_ctx_init_real_arb, gr_ctx_init_real_ca, gr_ctx_init_real_float_arf, gr_ctx_init_real_qqbar, gr_ctx_init_vector_gr_vec, gr_ctx_init_vector_space_gr_vec, gr_ctx_is_algebraically_closed, gr_ctx_is_canonical, gr_ctx_is_commutative_ring, gr_ctx_is_exact, gr_ctx_is_field, gr_ctx_is_finite, gr_ctx_is_finite_characteristic, gr_ctx_is_integral_domain, gr_ctx_is_multiplicative_group, gr_ctx_is_ordered_ring, gr_ctx_is_ring, gr_ctx_is_threadsafe, gr_ctx_is_unique_factorization_domain, gr_ctx_matrix_is_fixed_size, gr_ctx_print, gr_ctx_println, gr_ctx_set_real_prec, gr_ctx_sizeof_ctx, gr_ctx_sizeof_elem, gr_ctx_vector_gr_vec_is_fixed_size, gr_ctx_write, gr_dedekind_eta, gr_dedekind_eta_q, gr_digamma, gr_dilog, gr_dirichlet_beta, gr_dirichlet_chi_fmpz, gr_dirichlet_chi_vec, gr_dirichlet_eta, gr_dirichlet_hardy_theta, gr_dirichlet_hardy_z, gr_dirichlet_l, gr_div, gr_div_fmpq, gr_div_fmpz, gr_div_other, gr_div_si, gr_div_ui, gr_divexact, gr_divexact_fmpq, gr_divexact_fmpz, gr_divexact_other, gr_divexact_si, gr_divexact_ui, gr_divides, gr_dot_other, gr_doublefac, gr_doublefac_ui, gr_eisenstein_e, gr_eisenstein_g, gr_eisenstein_g_vec, gr_elliptic_e, gr_elliptic_e_inc, gr_elliptic_f, gr_elliptic_invariants, gr_elliptic_k, gr_elliptic_pi, gr_elliptic_pi_inc, gr_elliptic_roots, gr_equal, gr_erf, gr_erfc, gr_erfcinv, gr_erfcx, gr_erfi, gr_erfinv, gr_euclidean_div, gr_euclidean_divrem, gr_euclidean_rem, gr_euler, gr_eulernum_fmpz, gr_eulernum_ui, gr_eulernum_vec, gr_eulerpoly_ui, gr_evaluate_fmpz_mpoly_iter, gr_exp, gr_exp10, gr_exp2, gr_exp_integral, gr_exp_integral_ei, gr_exp_pi_i, gr_expm1, gr_fac, gr_fac_fmpz, gr_fac_ui, gr_fac_vec, gr_factor, gr_falling, gr_falling_ui, gr_fib_fmpz, gr_fib_ui, gr_fib_vec, gr_floor, gr_fmms, gr_fmpz_mpoly_evaluate, gr_fmpz_mpoly_evaluate_horner, gr_fmpz_poly_evaluate, gr_fmpz_poly_evaluate_horner, gr_fmpz_poly_evaluate_rectangular, gr_fq_frobenius, gr_fq_is_primitive, gr_fq_multiplicative_order, gr_fq_norm, gr_fq_pth_root, gr_fq_trace, gr_fresnel, gr_fresnel_c, gr_fresnel_s, gr_gamma, gr_gamma_fmpq, gr_gamma_fmpz, gr_gamma_lower, gr_gamma_upper, gr_gcd, gr_gegenbauer_c, gr_gen, gr_generic_acot, gr_generic_acoth, gr_generic_acsc, gr_generic_acsch, gr_generic_add_fmpq, gr_generic_add_fmpz, gr_generic_add_other, gr_generic_add_si, gr_generic_add_ui, gr_generic_addmul, gr_generic_addmul_fmpq, gr_generic_addmul_fmpz, gr_generic_addmul_other, gr_generic_addmul_si, gr_generic_addmul_ui, gr_generic_asec, gr_generic_asech, gr_generic_asin, gr_generic_asinh, gr_generic_atan, gr_generic_atanh, gr_generic_bellnum_fmpz, gr_generic_bellnum_ui, gr_generic_bellnum_vec, gr_generic_bernoulli_fmpz, gr_generic_bernoulli_ui, gr_generic_bernoulli_vec, gr_generic_beta, gr_generic_bin, gr_generic_bin_ui, gr_generic_bin_ui_vec, gr_generic_bin_uiui, gr_generic_bin_vec, gr_generic_chebyshev_t2_fmpz, gr_generic_chebyshev_t_fmpz, gr_generic_chebyshev_u2_fmpz, gr_generic_chebyshev_u_fmpz, gr_generic_cmp, gr_generic_cmp_other, gr_generic_cmpabs, gr_generic_cmpabs_other, gr_generic_cos, gr_generic_ctx_clear, gr_generic_ctx_predicate, gr_generic_ctx_predicate_false, gr_generic_ctx_predicate_true, gr_generic_div_fmpq, gr_generic_div_fmpz, gr_generic_div_other, gr_generic_div_si, gr_generic_div_ui, gr_generic_divexact, gr_generic_doublefac, gr_generic_doublefac_ui, gr_generic_erfcx, gr_generic_eulernum_fmpz, gr_generic_eulernum_ui, gr_generic_eulernum_vec, gr_generic_exp, gr_generic_exp10, gr_generic_exp2, gr_generic_expm1, gr_generic_fac, gr_generic_fac_fmpz, gr_generic_fac_ui, gr_generic_fac_vec, gr_generic_falling, gr_generic_falling_ui, gr_generic_fib2_fmpz, gr_generic_fib_fmpz, gr_generic_fib_ui, gr_generic_fib_vec, gr_generic_get_fmpz_2exp_fmpz, gr_generic_harmonic, gr_generic_harmonic_ui, gr_generic_hilbert_class_poly, gr_generic_inv, gr_generic_is_invertible, gr_generic_is_neg_one, gr_generic_is_one, gr_generic_is_square, gr_generic_is_zero, gr_generic_log, gr_generic_log10, gr_generic_log1p, gr_generic_log2, gr_generic_mul_2exp_fmpz, gr_generic_mul_2exp_si, gr_generic_mul_fmpq, gr_generic_mul_fmpz, gr_generic_mul_other, gr_generic_mul_si, gr_generic_mul_two, gr_generic_mul_ui, gr_generic_mul_ui_via_ZZ, gr_generic_neg_one, gr_generic_other_add, gr_generic_other_add_vec, gr_generic_other_div, gr_generic_other_div_vec, gr_generic_other_divexact_vec, gr_generic_other_mul, gr_generic_other_mul_vec, gr_generic_other_pow, gr_generic_other_pow_vec, gr_generic_other_sub, gr_generic_other_sub_vec, gr_generic_partitions_fmpz, gr_generic_partitions_ui, gr_generic_partitions_vec, gr_generic_pow_fmpq, gr_generic_pow_fmpz, gr_generic_pow_fmpz_binexp, gr_generic_pow_other, gr_generic_pow_si, gr_generic_pow_ui, gr_generic_pow_ui_binexp, gr_generic_randtest_not_zero, gr_generic_rfac, gr_generic_rfac_fmpz, gr_generic_rfac_ui, gr_generic_rfac_vec, gr_generic_rising, gr_generic_rising_ui, gr_generic_rsqrt, gr_generic_scalar_add_vec, gr_generic_scalar_div_vec, gr_generic_scalar_divexact_vec, gr_generic_scalar_mul_vec, gr_generic_scalar_other_add_vec, gr_generic_scalar_other_div_vec, gr_generic_scalar_other_divexact_vec, gr_generic_scalar_other_mul_vec, gr_generic_scalar_other_pow_vec, gr_generic_scalar_other_sub_vec, gr_generic_scalar_pow_vec, gr_generic_scalar_sub_vec, gr_generic_set_fmpq, gr_generic_set_fmpz_2exp_fmpz, gr_generic_set_other, gr_generic_set_shallow, gr_generic_sin, gr_generic_sin_cos, gr_generic_sqr, gr_generic_sqrt, gr_generic_stirling_s1_ui_vec, gr_generic_stirling_s1_uiui, gr_generic_stirling_s1u_ui_vec, gr_generic_stirling_s1u_uiui, gr_generic_stirling_s2_ui_vec, gr_generic_stirling_s2_uiui, gr_generic_sub_fmpq, gr_generic_sub_fmpz, gr_generic_sub_other, gr_generic_sub_si, gr_generic_sub_ui, gr_generic_submul, gr_generic_submul_fmpq, gr_generic_submul_fmpz, gr_generic_submul_other, gr_generic_submul_si, gr_generic_submul_ui, gr_generic_tan, gr_generic_vec_add, gr_generic_vec_add_other, gr_generic_vec_add_scalar, gr_generic_vec_add_scalar_fmpq, gr_generic_vec_add_scalar_fmpz, gr_generic_vec_add_scalar_other, gr_generic_vec_add_scalar_si, gr_generic_vec_add_scalar_ui, gr_generic_vec_clear, gr_generic_vec_div, gr_generic_vec_div_other, gr_generic_vec_div_scalar, gr_generic_vec_div_scalar_fmpq, gr_generic_vec_div_scalar_fmpz, gr_generic_vec_div_scalar_other, gr_generic_vec_div_scalar_si, gr_generic_vec_div_scalar_ui, gr_generic_vec_divexact, gr_generic_vec_divexact_other, gr_generic_vec_divexact_scalar, gr_generic_vec_divexact_scalar_fmpq, gr_generic_vec_divexact_scalar_fmpz, gr_generic_vec_divexact_scalar_other, gr_generic_vec_divexact_scalar_si, gr_generic_vec_divexact_scalar_ui, gr_generic_vec_dot, gr_generic_vec_dot_fmpz, gr_generic_vec_dot_rev, gr_generic_vec_dot_si, gr_generic_vec_dot_ui, gr_generic_vec_equal, gr_generic_vec_init, gr_generic_vec_is_zero, gr_generic_vec_mul, gr_generic_vec_mul_other, gr_generic_vec_mul_scalar, gr_generic_vec_mul_scalar_2exp_si, gr_generic_vec_mul_scalar_fmpq, gr_generic_vec_mul_scalar_fmpz, gr_generic_vec_mul_scalar_other, gr_generic_vec_mul_scalar_si, gr_generic_vec_mul_scalar_ui, gr_generic_vec_neg, gr_generic_vec_normalise, gr_generic_vec_normalise_weak, gr_generic_vec_pow, gr_generic_vec_pow_other, gr_generic_vec_pow_scalar, gr_generic_vec_pow_scalar_fmpq, gr_generic_vec_pow_scalar_fmpz, gr_generic_vec_pow_scalar_other, gr_generic_vec_pow_scalar_si, gr_generic_vec_pow_scalar_ui, gr_generic_vec_reciprocals, gr_generic_vec_scalar_addmul, gr_generic_vec_scalar_addmul_si, gr_generic_vec_scalar_submul, gr_generic_vec_scalar_submul_si, gr_generic_vec_set, gr_generic_vec_set_powers, gr_generic_vec_sub, gr_generic_vec_sub_other, gr_generic_vec_sub_scalar, gr_generic_vec_sub_scalar_fmpq, gr_generic_vec_sub_scalar_fmpz, gr_generic_vec_sub_scalar_other, gr_generic_vec_sub_scalar_si, gr_generic_vec_sub_scalar_ui, gr_generic_vec_swap, gr_generic_vec_zero, gr_generic_write_n, gr_get_d, gr_get_fmpq, gr_get_fmpz, gr_get_fmpz_2exp_fmpz, gr_get_si, gr_get_str, gr_get_str_n, gr_get_ui, gr_glaisher, gr_harmonic, gr_harmonic_ui, gr_heap_clear, gr_heap_clear_vec, gr_heap_init, gr_heap_init_vec, gr_hermite_h, gr_hilbert_class_poly, gr_hurwitz_zeta, gr_hypgeom_0f1, gr_hypgeom_1f1, gr_hypgeom_2f1, gr_hypgeom_pfq, gr_hypgeom_u, gr_i, gr_im, gr_init, gr_inv, gr_is_invertible, gr_is_neg_one, gr_is_one, gr_is_square, gr_is_zero, gr_jacobi_p, gr_jacobi_theta, gr_jacobi_theta_1, gr_jacobi_theta_2, gr_jacobi_theta_3, gr_jacobi_theta_4, gr_khinchin, gr_laguerre_l, gr_lambertw, gr_lambertw_fmpz, gr_lcm, gr_legendre_p, gr_legendre_p_root_ui, gr_legendre_q, gr_lerch_phi, gr_lgamma, gr_log, gr_log10, gr_log1p, gr_log2, gr_log_barnes_g, gr_log_integral, gr_log_pi_i, gr_mat_add, gr_mat_add_scalar, gr_mat_addmul_scalar, gr_mat_adjugate, gr_mat_adjugate_charpoly, gr_mat_adjugate_cofactor, gr_mat_apply_row_similarity, gr_mat_charpoly, gr_mat_charpoly_berkowitz, gr_mat_charpoly_danilevsky, gr_mat_charpoly_faddeev, gr_mat_charpoly_faddeev_bsgs, gr_mat_charpoly_from_hessenberg, gr_mat_charpoly_gauss, gr_mat_charpoly_householder, gr_mat_clear, gr_mat_concat_horizontal, gr_mat_concat_vertical, gr_mat_det, gr_mat_det_berkowitz, gr_mat_det_cofactor, gr_mat_det_fflu, gr_mat_det_generic, gr_mat_det_generic_field, gr_mat_det_generic_integral_domain, gr_mat_det_lu, gr_mat_diag_mul, gr_mat_diagonalization, gr_mat_diagonalization_generic, gr_mat_diagonalization_precomp, gr_mat_div_scalar, gr_mat_eigenvalues, gr_mat_eigenvalues_other, gr_mat_entry_ptr, gr_mat_entry_srcptr, gr_mat_equal, gr_mat_exp, gr_mat_exp_jordan, gr_mat_fflu, gr_mat_find_nonzero_pivot, gr_mat_find_nonzero_pivot_generic, gr_mat_find_nonzero_pivot_large_abs, gr_mat_gr_poly_evaluate, gr_mat_hadamard, gr_mat_hessenberg, gr_mat_hessenberg_gauss, gr_mat_hessenberg_householder, gr_mat_hilbert, gr_mat_init, gr_mat_init_set, gr_mat_inv, gr_mat_invert_cols, gr_mat_invert_rows, gr_mat_is_diagonal, gr_mat_is_empty, gr_mat_is_hessenberg, gr_mat_is_lower_triangular, gr_mat_is_neg_one, gr_mat_is_one, gr_mat_is_scalar, gr_mat_is_square, gr_mat_is_upper_triangular, gr_mat_is_zero, gr_mat_jordan_blocks, gr_mat_jordan_form, gr_mat_jordan_transformation, gr_mat_log, gr_mat_log_jordan, gr_mat_lu, gr_mat_lu_classical, gr_mat_lu_recursive, gr_mat_minpoly_field, gr_mat_mul, gr_mat_mul_classical, gr_mat_mul_diag, gr_mat_mul_generic, gr_mat_mul_scalar, gr_mat_neg, gr_mat_nonsingular_solve, gr_mat_nonsingular_solve_den, gr_mat_nonsingular_solve_den_fflu, gr_mat_nonsingular_solve_fflu, gr_mat_nonsingular_solve_fflu_precomp, gr_mat_nonsingular_solve_lu, gr_mat_nonsingular_solve_lu_precomp, gr_mat_nonsingular_solve_tril, gr_mat_nonsingular_solve_tril_classical, gr_mat_nonsingular_solve_tril_recursive, gr_mat_nonsingular_solve_triu, gr_mat_nonsingular_solve_triu_classical, gr_mat_nonsingular_solve_triu_recursive, gr_mat_nullspace, gr_mat_one, gr_mat_ones, gr_mat_pascal, gr_mat_print, gr_mat_randops, gr_mat_randpermdiag, gr_mat_randrank, gr_mat_randtest, gr_mat_rank, gr_mat_rank_fflu, gr_mat_rank_lu, gr_mat_reduce_row, gr_mat_rref, gr_mat_rref_den, gr_mat_rref_den_fflu, gr_mat_rref_fflu, gr_mat_rref_lu, gr_mat_set, gr_mat_set_fmpq, gr_mat_set_fmpq_mat, gr_mat_set_fmpz, gr_mat_set_fmpz_mat, gr_mat_set_jordan_blocks, gr_mat_set_scalar, gr_mat_set_si, gr_mat_set_ui, gr_mat_solve_field, gr_mat_sqr, gr_mat_stirling, gr_mat_sub, gr_mat_sub_scalar, gr_mat_submul_scalar, gr_mat_swap, gr_mat_swap_cols, gr_mat_swap_entrywise, gr_mat_swap_rows, gr_mat_trace, gr_mat_trace_prod2, gr_mat_transpose, gr_mat_transpose_resize, gr_mat_window_clear, gr_mat_window_init, gr_mat_write, gr_mat_zero, gr_method_tab_init, gr_modular_delta, gr_modular_j, gr_modular_lambda, gr_mpoly_add, gr_mpoly_assert_canonical, gr_mpoly_clear, gr_mpoly_combine_like_terms, gr_mpoly_equal, gr_mpoly_fit_bits, gr_mpoly_fit_length, gr_mpoly_fit_length_fit_bits, gr_mpoly_fit_length_reset_bits, gr_mpoly_gen, gr_mpoly_get_coeff_scalar_fmpz, gr_mpoly_get_coeff_scalar_ui, gr_mpoly_init, gr_mpoly_init2, gr_mpoly_init3, gr_mpoly_is_canonical, gr_mpoly_is_gen, gr_mpoly_is_one, gr_mpoly_is_zero, gr_mpoly_mul, gr_mpoly_mul_fmpq, gr_mpoly_mul_fmpz, gr_mpoly_mul_johnson, gr_mpoly_mul_monomial, gr_mpoly_mul_scalar, gr_mpoly_mul_si, gr_mpoly_mul_ui, gr_mpoly_neg, gr_mpoly_one, gr_mpoly_print_pretty, gr_mpoly_push_term_scalar_fmpz, gr_mpoly_push_term_scalar_ui, gr_mpoly_randtest_bits, gr_mpoly_randtest_bound, gr_mpoly_set, gr_mpoly_set_coeff_fmpq_fmpz, gr_mpoly_set_coeff_fmpq_ui, gr_mpoly_set_coeff_fmpz_fmpz, gr_mpoly_set_coeff_fmpz_ui, gr_mpoly_set_coeff_scalar_fmpz, gr_mpoly_set_coeff_scalar_ui, gr_mpoly_set_coeff_si_fmpz, gr_mpoly_set_coeff_si_ui, gr_mpoly_set_coeff_ui_fmpz, gr_mpoly_set_coeff_ui_ui, gr_mpoly_set_fmpq, gr_mpoly_set_fmpz, gr_mpoly_set_scalar, gr_mpoly_set_si, gr_mpoly_set_ui, gr_mpoly_sort_terms, gr_mpoly_sub, gr_mpoly_swap, gr_mpoly_write_pretty, gr_mpoly_zero, gr_mul, gr_mul_2exp_fmpz, gr_mul_2exp_si, gr_mul_fmpq, gr_mul_fmpz, gr_mul_other, gr_mul_si, gr_mul_two, gr_mul_ui, gr_neg, gr_neg_one, gr_nint, gr_not_equal, gr_not_implemented, gr_not_in_domain, gr_one, gr_other_add, gr_other_div, gr_other_divexact, gr_other_mul, gr_other_pow, gr_other_sub, gr_partitions_fmpz, gr_partitions_ui, gr_partitions_vec, gr_pi, gr_poly_acos_series, gr_poly_acosh_series, gr_poly_add, gr_poly_add_series, gr_poly_asin_series, gr_poly_asinh_series, gr_poly_atan_series, gr_poly_atanh_series, gr_poly_clear, gr_poly_compose, gr_poly_compose_divconquer, gr_poly_compose_horner, gr_poly_compose_series, gr_poly_compose_series_brent_kung, gr_poly_compose_series_divconquer, gr_poly_compose_series_horner, gr_poly_derivative, gr_poly_div, gr_poly_div_basecase, gr_poly_div_divconquer, gr_poly_div_newton, gr_poly_div_series, gr_poly_div_series_basecase, gr_poly_div_series_invmul, gr_poly_div_series_newton, gr_poly_divrem, gr_poly_divrem_basecase, gr_poly_divrem_divconquer, gr_poly_divrem_newton, gr_poly_entry_ptr, gr_poly_equal, gr_poly_evaluate, gr_poly_evaluate_horner, gr_poly_evaluate_other, gr_poly_evaluate_other_horner, gr_poly_evaluate_other_rectangular, gr_poly_evaluate_rectangular, gr_poly_evaluate_vec_fast, gr_poly_evaluate_vec_iter, gr_poly_exp_series, gr_poly_exp_series_basecase, gr_poly_exp_series_basecase_mul, gr_poly_exp_series_newton, gr_poly_factor_squarefree, gr_poly_fit_length, gr_poly_gcd, gr_poly_gcd_euclidean, gr_poly_gcd_hgcd, gr_poly_gen, gr_poly_get_coeff_scalar, gr_poly_init, gr_poly_init2, gr_poly_integral, gr_poly_inv, gr_poly_inv_series, gr_poly_inv_series_basecase, gr_poly_inv_series_newton, gr_poly_is_gen, gr_poly_is_monic, gr_poly_is_one, gr_poly_is_zero, gr_poly_length, gr_poly_log1p_series, gr_poly_log_series, gr_poly_make_monic, gr_poly_mul, gr_poly_mul_scalar, gr_poly_mullow, gr_poly_neg, gr_poly_neg_one, gr_poly_nth_derivative, gr_poly_one, gr_poly_pow_fmpz, gr_poly_pow_series_fmpq_recurrence, gr_poly_pow_series_ui, gr_poly_pow_series_ui_binexp, gr_poly_pow_ui, gr_poly_pow_ui_binexp, gr_poly_print, gr_poly_randtest, gr_poly_rem, gr_poly_resultant, gr_poly_resultant_euclidean, gr_poly_resultant_hgcd, gr_poly_resultant_small, gr_poly_resultant_sylvester, gr_poly_reverse, gr_poly_roots, gr_poly_roots_other, gr_poly_rsqrt_series, gr_poly_rsqrt_series_basecase, gr_poly_rsqrt_series_miller, gr_poly_rsqrt_series_newton, gr_poly_set, gr_poly_set_coeff_fmpq, gr_poly_set_coeff_fmpz, gr_poly_set_coeff_scalar, gr_poly_set_coeff_si, gr_poly_set_coeff_ui, gr_poly_set_fmpq, gr_poly_set_fmpq_poly, gr_poly_set_fmpz, gr_poly_set_fmpz_poly, gr_poly_set_gr_poly_other, gr_poly_set_scalar, gr_poly_set_si, gr_poly_set_ui, gr_poly_shift_left, gr_poly_shift_right, gr_poly_sin_cos_series_basecase, gr_poly_sin_cos_series_tangent, gr_poly_sqrt_series, gr_poly_sqrt_series_basecase, gr_poly_sqrt_series_miller, gr_poly_sqrt_series_newton, gr_poly_squarefree_part, gr_poly_sub, gr_poly_sub_series, gr_poly_swap, gr_poly_tan_series, gr_poly_tan_series_basecase, gr_poly_tan_series_newton, gr_poly_taylor_shift, gr_poly_taylor_shift_convolution, gr_poly_taylor_shift_divconquer, gr_poly_taylor_shift_horner, gr_poly_truncate, gr_poly_write, gr_poly_xgcd_euclidean, gr_poly_xgcd_hgcd, gr_poly_zero, gr_polygamma, gr_polylog, gr_pow, gr_pow_fmpq, gr_pow_fmpz, gr_pow_other, gr_pow_si, gr_pow_ui, gr_print, gr_println, gr_randtest, gr_randtest_not_zero, gr_randtest_small, gr_re, gr_rfac, gr_rfac_fmpz, gr_rfac_ui, gr_rfac_vec, gr_rgamma, gr_riemann_xi, gr_rising, gr_rising_ui, gr_rising_ui_forward, gr_rsqrt, gr_sec, gr_sec_pi, gr_sech, gr_series_acos, gr_series_acosh, gr_series_add, gr_series_agm1, gr_series_airy, gr_series_airy_ai, gr_series_airy_ai_prime, gr_series_airy_bi, gr_series_airy_bi_prime, gr_series_asin, gr_series_asinh, gr_series_atan, gr_series_atanh, gr_series_beta_lower, gr_series_clear, gr_series_cos_integral, gr_series_cosh_integral, gr_series_digamma, gr_series_dirichlet_hardy_theta, gr_series_dirichlet_hardy_z, gr_series_dirichlet_l, gr_series_div, gr_series_elliptic_k, gr_series_equal, gr_series_erf, gr_series_erfc, gr_series_erfi, gr_series_exp, gr_series_exp_integral_ei, gr_series_fresnel, gr_series_fresnel_c, gr_series_fresnel_s, gr_series_gamma, gr_series_gamma_lower, gr_series_gamma_upper, gr_series_gen, gr_series_hurwitz_zeta, gr_series_hypgeom_pfq, gr_series_init, gr_series_inv, gr_series_is_one, gr_series_is_zero, gr_series_jacobi_theta, gr_series_jacobi_theta_1, gr_series_jacobi_theta_2, gr_series_jacobi_theta_3, gr_series_jacobi_theta_4, gr_series_lgamma, gr_series_log, gr_series_log_integral, gr_series_make_exact, gr_series_mul, gr_series_neg, gr_series_one, gr_series_polylog, gr_series_randtest, gr_series_rgamma, gr_series_rsqrt, gr_series_set, gr_series_set_fmpq, gr_series_set_fmpz, gr_series_set_gr_poly, gr_series_set_scalar, gr_series_set_si, gr_series_set_ui, gr_series_sin_integral, gr_series_sinh_integral, gr_series_sqrt, gr_series_sub, gr_series_swap, gr_series_tan, gr_series_weierstrass_p, gr_series_write, gr_series_zero, gr_set, gr_set_d, gr_set_fmpq, gr_set_fmpz, gr_set_fmpz_2exp_fmpz, gr_set_other, gr_set_shallow, gr_set_si, gr_set_str, gr_set_ui, gr_sgn, gr_sin, gr_sin_cos, gr_sin_cos_pi, gr_sin_integral, gr_sin_pi, gr_sinc, gr_sinc_pi, gr_sinh, gr_sinh_cosh, gr_sinh_integral, gr_spherical_y_si, gr_sqr, gr_sqrt, gr_stieltjes, gr_stirling_s1_ui_vec, gr_stirling_s1_uiui, gr_stirling_s1u_ui_vec, gr_stirling_s1u_uiui, gr_stirling_s2_ui_vec, gr_stirling_s2_uiui, gr_stream_init_file, gr_stream_init_str, gr_stream_write, gr_stream_write_fmpz, gr_stream_write_free, gr_stream_write_si, gr_stream_write_ui, gr_sub, gr_sub_fmpq, gr_sub_fmpz, gr_sub_other, gr_sub_si, gr_sub_ui, gr_submul, gr_submul_fmpq, gr_submul_fmpz, gr_submul_other, gr_submul_si, gr_submul_ui, gr_swap, gr_swap2, gr_tan, gr_tan_pi, gr_tanh, gr_test_add_aliasing, gr_test_add_associative, gr_test_add_commutative, gr_test_add_type_variants, gr_test_addmul_submul, gr_test_addmul_type_variants, gr_test_binary_op_aliasing, gr_test_binary_op_associative, gr_test_binary_op_commutative, gr_test_binary_op_left_distributive, gr_test_binary_op_right_distributive, gr_test_binary_op_type_variants, gr_test_complex_parts, gr_test_div_right_distributive, gr_test_div_then_mul, gr_test_div_type_variants, gr_test_divexact, gr_test_divexact_type_variants, gr_test_equal, gr_test_field, gr_test_get_fmpq, gr_test_get_fmpz, gr_test_get_fmpz_2exp_fmpz, gr_test_get_si, gr_test_get_ui, gr_test_init_clear, gr_test_integral_domain, gr_test_inv_involution, gr_test_inv_multiplication, gr_test_iter, gr_test_mat_mul_classical_associative, gr_test_mul_2exp_fmpz, gr_test_mul_2exp_si, gr_test_mul_aliasing, gr_test_mul_associative, gr_test_mul_commutative, gr_test_mul_left_distributive, gr_test_mul_right_distributive, gr_test_mul_then_div, gr_test_mul_type_variants, gr_test_multiplicative_group, gr_test_neg, gr_test_one, gr_test_ordered_ring_cmp, gr_test_ordered_ring_cmpabs, gr_test_pow_fmpz_exponent_addition, gr_test_pow_ui_aliasing, gr_test_pow_ui_base_multiplication, gr_test_pow_ui_base_scalar_multiplication, gr_test_pow_ui_exponent_addition, gr_test_randtest_not_zero, gr_test_ring, gr_test_rsqrt, gr_test_set_fmpq, gr_test_set_fmpz, gr_test_set_si, gr_test_set_ui, gr_test_sqrt, gr_test_sub_aliasing, gr_test_sub_equal_neg_add, gr_test_sub_type_variants, gr_test_submul_type_variants, gr_test_swap, gr_test_vec_add, gr_test_vec_binary_op, gr_test_vec_div, gr_test_vec_divexact, gr_test_vec_dot, gr_test_vec_mul, gr_test_vec_pow, gr_test_vec_sub, gr_test_zero_one, gr_trunc, gr_vec_append, gr_vec_clear, gr_vec_entry_ptr, gr_vec_entry_srcptr, gr_vec_fit_length, gr_vec_init, gr_vec_length, gr_vec_print, gr_vec_set, gr_vec_set_length, gr_vec_write, gr_weierstrass_p, gr_weierstrass_p_inv, gr_weierstrass_p_prime, gr_weierstrass_sigma, gr_weierstrass_zeta, gr_write, gr_write_n, gr_zero, gr_zeta, gr_zeta_nzeros, gr_zeta_ui, gr_zeta_zero, gr_zeta_zero_vec`` +* ``gr_abs, gr_acos, gr_acos_pi, gr_acosh, gr_acot, gr_acot_pi, gr_acoth, gr_acsc, gr_acsc_pi, gr_acsch, gr_add, gr_add_fmpq, gr_add_fmpz, gr_add_other, gr_add_si, gr_add_ui, gr_addmul, gr_addmul_fmpq, gr_addmul_fmpz, gr_addmul_other, gr_addmul_si, gr_addmul_ui, gr_agm, gr_agm1, gr_airy, gr_airy_ai, gr_airy_ai_prime, gr_airy_ai_prime_zero, gr_airy_ai_zero, gr_airy_bi, gr_airy_bi_prime, gr_airy_bi_prime_zero, gr_airy_bi_zero, gr_asec, gr_asec_pi, gr_asech, gr_asin, gr_asin_pi, gr_asinh, gr_atan, gr_atan2, gr_atan_pi, gr_atanh, gr_barnes_g, gr_bellnum_fmpz, gr_bellnum_ui, gr_bellnum_vec, gr_bernoulli_fmpz, gr_bernoulli_ui, gr_bernoulli_vec, gr_bernpoly_ui, gr_bessel_i, gr_bessel_i_scaled, gr_bessel_j, gr_bessel_j_y, gr_bessel_k, gr_bessel_k_scaled, gr_bessel_y, gr_beta, gr_beta_lower, gr_bin, gr_bin_ui, gr_bin_ui_vec, gr_bin_uiui, gr_bin_vec, gr_carlson_rc, gr_carlson_rd, gr_carlson_rf, gr_carlson_rg, gr_carlson_rj, gr_catalan, gr_ceil, gr_chebyshev_t, gr_chebyshev_t_fmpz, gr_chebyshev_u, gr_chebyshev_u_fmpz, gr_clear, gr_cmp, gr_cmp_other, gr_cmpabs, gr_cmpabs_other, gr_conj, gr_cos, gr_cos_integral, gr_cos_pi, gr_cosh, gr_cosh_integral, gr_cot, gr_cot_pi, gr_coth, gr_coulomb, gr_coulomb_f, gr_coulomb_g, gr_coulomb_hneg, gr_coulomb_hpos, gr_csc, gr_csc_pi, gr_csch, gr_csgn, gr_ctx_ca_get_option, gr_ctx_ca_set_option, gr_ctx_clear, gr_ctx_cmp_coercion, gr_ctx_data_as_ptr, gr_ctx_data_ptr, gr_ctx_fmpz_mod_set_primality, gr_ctx_fq_degree, gr_ctx_fq_order, gr_ctx_fq_prime, gr_ctx_get_real_prec, gr_ctx_get_str, gr_ctx_has_real_prec, gr_ctx_init_complex_acb, gr_ctx_init_complex_algebraic_ca, gr_ctx_init_complex_ca, gr_ctx_init_complex_float_acf, gr_ctx_init_complex_qqbar, gr_ctx_init_dirichlet_group, gr_ctx_init_fmpq, gr_ctx_init_fmpz, gr_ctx_init_fmpz_mod, gr_ctx_init_fmpz_poly, gr_ctx_init_fmpzi, gr_ctx_init_fq, gr_ctx_init_fq_nmod, gr_ctx_init_fq_zech, gr_ctx_init_gr_series, gr_ctx_init_gr_series_mod, gr_ctx_init_matrix_domain, gr_ctx_init_matrix_ring, gr_ctx_init_matrix_space, gr_ctx_init_gr_mpoly, gr_ctx_init_nf, gr_ctx_init_nf_fmpq_poly, gr_ctx_init_nmod, gr_ctx_init_nmod8, gr_ctx_init_nmod32, gr_ctx_init_perm, gr_ctx_init_gr_poly, gr_ctx_init_psl2z, gr_ctx_init_random, gr_ctx_init_real_algebraic_ca, gr_ctx_init_real_arb, gr_ctx_init_real_ca, gr_ctx_init_real_float_arf, gr_ctx_init_real_qqbar, gr_ctx_init_vector_gr_vec, gr_ctx_init_vector_space_gr_vec, gr_ctx_is_algebraically_closed, gr_ctx_is_canonical, gr_ctx_is_commutative_ring, gr_ctx_is_exact, gr_ctx_is_field, gr_ctx_is_finite, gr_ctx_is_finite_characteristic, gr_ctx_is_integral_domain, gr_ctx_is_multiplicative_group, gr_ctx_is_ordered_ring, gr_ctx_is_ring, gr_ctx_is_threadsafe, gr_ctx_is_unique_factorization_domain, gr_ctx_matrix_is_fixed_size, gr_ctx_print, gr_ctx_println, gr_ctx_set_real_prec, gr_ctx_sizeof_ctx, gr_ctx_sizeof_elem, gr_ctx_vector_gr_vec_is_fixed_size, gr_ctx_write, gr_dedekind_eta, gr_dedekind_eta_q, gr_digamma, gr_dilog, gr_dirichlet_beta, gr_dirichlet_chi_fmpz, gr_dirichlet_chi_vec, gr_dirichlet_eta, gr_dirichlet_hardy_theta, gr_dirichlet_hardy_z, gr_dirichlet_l, gr_div, gr_div_fmpq, gr_div_fmpz, gr_div_other, gr_div_si, gr_div_ui, gr_divexact, gr_divexact_fmpq, gr_divexact_fmpz, gr_divexact_other, gr_divexact_si, gr_divexact_ui, gr_divides, gr_dot_other, gr_doublefac, gr_doublefac_ui, gr_eisenstein_e, gr_eisenstein_g, gr_eisenstein_g_vec, gr_elliptic_e, gr_elliptic_e_inc, gr_elliptic_f, gr_elliptic_invariants, gr_elliptic_k, gr_elliptic_pi, gr_elliptic_pi_inc, gr_elliptic_roots, gr_equal, gr_erf, gr_erfc, gr_erfcinv, gr_erfcx, gr_erfi, gr_erfinv, gr_euclidean_div, gr_euclidean_divrem, gr_euclidean_rem, gr_euler, gr_eulernum_fmpz, gr_eulernum_ui, gr_eulernum_vec, gr_eulerpoly_ui, gr_evaluate_fmpz_mpoly_iter, gr_exp, gr_exp10, gr_exp2, gr_exp_integral, gr_exp_integral_ei, gr_exp_pi_i, gr_expm1, gr_fac, gr_fac_fmpz, gr_fac_ui, gr_fac_vec, gr_factor, gr_falling, gr_falling_ui, gr_fib_fmpz, gr_fib_ui, gr_fib_vec, gr_floor, gr_fmms, gr_fmpz_mpoly_evaluate, gr_fmpz_mpoly_evaluate_horner, gr_fmpz_poly_evaluate, gr_fmpz_poly_evaluate_horner, gr_fmpz_poly_evaluate_rectangular, gr_fq_frobenius, gr_fq_is_primitive, gr_fq_multiplicative_order, gr_fq_norm, gr_fq_pth_root, gr_fq_trace, gr_fresnel, gr_fresnel_c, gr_fresnel_s, gr_gamma, gr_gamma_fmpq, gr_gamma_fmpz, gr_gamma_lower, gr_gamma_upper, gr_gcd, gr_gegenbauer_c, gr_gen, gr_generic_acot, gr_generic_acoth, gr_generic_acsc, gr_generic_acsch, gr_generic_add_fmpq, gr_generic_add_fmpz, gr_generic_add_other, gr_generic_add_si, gr_generic_add_ui, gr_generic_addmul, gr_generic_addmul_fmpq, gr_generic_addmul_fmpz, gr_generic_addmul_other, gr_generic_addmul_si, gr_generic_addmul_ui, gr_generic_asec, gr_generic_asech, gr_generic_asin, gr_generic_asinh, gr_generic_atan, gr_generic_atanh, gr_generic_bellnum_fmpz, gr_generic_bellnum_ui, gr_generic_bellnum_vec, gr_generic_bernoulli_fmpz, gr_generic_bernoulli_ui, gr_generic_bernoulli_vec, gr_generic_beta, gr_generic_bin, gr_generic_bin_ui, gr_generic_bin_ui_vec, gr_generic_bin_uiui, gr_generic_bin_vec, gr_generic_chebyshev_t2_fmpz, gr_generic_chebyshev_t_fmpz, gr_generic_chebyshev_u2_fmpz, gr_generic_chebyshev_u_fmpz, gr_generic_cmp, gr_generic_cmp_other, gr_generic_cmpabs, gr_generic_cmpabs_other, gr_generic_cos, gr_generic_ctx_clear, gr_generic_ctx_predicate, gr_generic_ctx_predicate_false, gr_generic_ctx_predicate_true, gr_generic_div_fmpq, gr_generic_div_fmpz, gr_generic_div_other, gr_generic_div_si, gr_generic_div_ui, gr_generic_divexact, gr_generic_doublefac, gr_generic_doublefac_ui, gr_generic_erfcx, gr_generic_eulernum_fmpz, gr_generic_eulernum_ui, gr_generic_eulernum_vec, gr_generic_exp, gr_generic_exp10, gr_generic_exp2, gr_generic_expm1, gr_generic_fac, gr_generic_fac_fmpz, gr_generic_fac_ui, gr_generic_fac_vec, gr_generic_falling, gr_generic_falling_ui, gr_generic_fib2_fmpz, gr_generic_fib_fmpz, gr_generic_fib_ui, gr_generic_fib_vec, gr_generic_get_fmpz_2exp_fmpz, gr_generic_harmonic, gr_generic_harmonic_ui, gr_generic_hilbert_class_poly, gr_generic_inv, gr_generic_is_invertible, gr_generic_is_neg_one, gr_generic_is_one, gr_generic_is_square, gr_generic_is_zero, gr_generic_log, gr_generic_log10, gr_generic_log1p, gr_generic_log2, gr_generic_mul_2exp_fmpz, gr_generic_mul_2exp_si, gr_generic_mul_fmpq, gr_generic_mul_fmpz, gr_generic_mul_other, gr_generic_mul_si, gr_generic_mul_two, gr_generic_mul_ui, gr_generic_mul_ui_via_ZZ, gr_generic_neg_one, gr_generic_other_add, gr_generic_other_add_vec, gr_generic_other_div, gr_generic_other_div_vec, gr_generic_other_divexact_vec, gr_generic_other_mul, gr_generic_other_mul_vec, gr_generic_other_pow, gr_generic_other_pow_vec, gr_generic_other_sub, gr_generic_other_sub_vec, gr_generic_partitions_fmpz, gr_generic_partitions_ui, gr_generic_partitions_vec, gr_generic_pow_fmpq, gr_generic_pow_fmpz, gr_generic_pow_fmpz_binexp, gr_generic_pow_other, gr_generic_pow_si, gr_generic_pow_ui, gr_generic_pow_ui_binexp, gr_generic_randtest_not_zero, gr_generic_rfac, gr_generic_rfac_fmpz, gr_generic_rfac_ui, gr_generic_rfac_vec, gr_generic_rising, gr_generic_rising_ui, gr_generic_rsqrt, gr_generic_scalar_add_vec, gr_generic_scalar_div_vec, gr_generic_scalar_divexact_vec, gr_generic_scalar_mul_vec, gr_generic_scalar_other_add_vec, gr_generic_scalar_other_div_vec, gr_generic_scalar_other_divexact_vec, gr_generic_scalar_other_mul_vec, gr_generic_scalar_other_pow_vec, gr_generic_scalar_other_sub_vec, gr_generic_scalar_pow_vec, gr_generic_scalar_sub_vec, gr_generic_set_fmpq, gr_generic_set_fmpz_2exp_fmpz, gr_generic_set_other, gr_generic_set_shallow, gr_generic_sin, gr_generic_sin_cos, gr_generic_sqr, gr_generic_sqrt, gr_generic_stirling_s1_ui_vec, gr_generic_stirling_s1_uiui, gr_generic_stirling_s1u_ui_vec, gr_generic_stirling_s1u_uiui, gr_generic_stirling_s2_ui_vec, gr_generic_stirling_s2_uiui, gr_generic_sub_fmpq, gr_generic_sub_fmpz, gr_generic_sub_other, gr_generic_sub_si, gr_generic_sub_ui, gr_generic_submul, gr_generic_submul_fmpq, gr_generic_submul_fmpz, gr_generic_submul_other, gr_generic_submul_si, gr_generic_submul_ui, gr_generic_tan, gr_generic_vec_add, gr_generic_vec_add_other, gr_generic_vec_add_scalar, gr_generic_vec_add_scalar_fmpq, gr_generic_vec_add_scalar_fmpz, gr_generic_vec_add_scalar_other, gr_generic_vec_add_scalar_si, gr_generic_vec_add_scalar_ui, gr_generic_vec_clear, gr_generic_vec_div, gr_generic_vec_div_other, gr_generic_vec_div_scalar, gr_generic_vec_div_scalar_fmpq, gr_generic_vec_div_scalar_fmpz, gr_generic_vec_div_scalar_other, gr_generic_vec_div_scalar_si, gr_generic_vec_div_scalar_ui, gr_generic_vec_divexact, gr_generic_vec_divexact_other, gr_generic_vec_divexact_scalar, gr_generic_vec_divexact_scalar_fmpq, gr_generic_vec_divexact_scalar_fmpz, gr_generic_vec_divexact_scalar_other, gr_generic_vec_divexact_scalar_si, gr_generic_vec_divexact_scalar_ui, gr_generic_vec_dot, gr_generic_vec_dot_fmpz, gr_generic_vec_dot_rev, gr_generic_vec_dot_si, gr_generic_vec_dot_ui, gr_generic_vec_equal, gr_generic_vec_init, gr_generic_vec_is_zero, gr_generic_vec_mul, gr_generic_vec_mul_other, gr_generic_vec_mul_scalar, gr_generic_vec_mul_scalar_2exp_si, gr_generic_vec_mul_scalar_fmpq, gr_generic_vec_mul_scalar_fmpz, gr_generic_vec_mul_scalar_other, gr_generic_vec_mul_scalar_si, gr_generic_vec_mul_scalar_ui, gr_generic_vec_neg, gr_generic_vec_normalise, gr_generic_vec_normalise_weak, gr_generic_vec_pow, gr_generic_vec_pow_other, gr_generic_vec_pow_scalar, gr_generic_vec_pow_scalar_fmpq, gr_generic_vec_pow_scalar_fmpz, gr_generic_vec_pow_scalar_other, gr_generic_vec_pow_scalar_si, gr_generic_vec_pow_scalar_ui, gr_generic_vec_reciprocals, gr_generic_vec_scalar_addmul, gr_generic_vec_scalar_addmul_si, gr_generic_vec_scalar_submul, gr_generic_vec_scalar_submul_si, gr_generic_vec_set, gr_generic_vec_set_powers, gr_generic_vec_sub, gr_generic_vec_sub_other, gr_generic_vec_sub_scalar, gr_generic_vec_sub_scalar_fmpq, gr_generic_vec_sub_scalar_fmpz, gr_generic_vec_sub_scalar_other, gr_generic_vec_sub_scalar_si, gr_generic_vec_sub_scalar_ui, gr_generic_vec_swap, gr_generic_vec_zero, gr_generic_write_n, gr_get_d, gr_get_fmpq, gr_get_fmpz, gr_get_fmpz_2exp_fmpz, gr_get_si, gr_get_str, gr_get_str_n, gr_get_ui, gr_glaisher, gr_harmonic, gr_harmonic_ui, gr_heap_clear, gr_heap_clear_vec, gr_heap_init, gr_heap_init_vec, gr_hermite_h, gr_hilbert_class_poly, gr_hurwitz_zeta, gr_hypgeom_0f1, gr_hypgeom_1f1, gr_hypgeom_2f1, gr_hypgeom_pfq, gr_hypgeom_u, gr_i, gr_im, gr_init, gr_inv, gr_is_invertible, gr_is_neg_one, gr_is_one, gr_is_square, gr_is_zero, gr_jacobi_p, gr_jacobi_theta, gr_jacobi_theta_1, gr_jacobi_theta_2, gr_jacobi_theta_3, gr_jacobi_theta_4, gr_khinchin, gr_laguerre_l, gr_lambertw, gr_lambertw_fmpz, gr_lcm, gr_legendre_p, gr_legendre_p_root_ui, gr_legendre_q, gr_lerch_phi, gr_lgamma, gr_log, gr_log10, gr_log1p, gr_log2, gr_log_barnes_g, gr_log_integral, gr_log_pi_i, gr_mat_add, gr_mat_add_scalar, gr_mat_addmul_scalar, gr_mat_adjugate, gr_mat_adjugate_charpoly, gr_mat_adjugate_cofactor, gr_mat_apply_row_similarity, gr_mat_charpoly, gr_mat_charpoly_berkowitz, gr_mat_charpoly_danilevsky, gr_mat_charpoly_faddeev, gr_mat_charpoly_faddeev_bsgs, gr_mat_charpoly_from_hessenberg, gr_mat_charpoly_gauss, gr_mat_charpoly_householder, gr_mat_clear, gr_mat_concat_horizontal, gr_mat_concat_vertical, gr_mat_det, gr_mat_det_berkowitz, gr_mat_det_cofactor, gr_mat_det_fflu, gr_mat_det_generic, gr_mat_det_generic_field, gr_mat_det_generic_integral_domain, gr_mat_det_lu, gr_mat_diag_mul, gr_mat_diagonalization, gr_mat_diagonalization_generic, gr_mat_diagonalization_precomp, gr_mat_div_scalar, gr_mat_eigenvalues, gr_mat_eigenvalues_other, gr_mat_entry_ptr, gr_mat_entry_srcptr, gr_mat_equal, gr_mat_exp, gr_mat_exp_jordan, gr_mat_fflu, gr_mat_find_nonzero_pivot, gr_mat_find_nonzero_pivot_generic, gr_mat_find_nonzero_pivot_large_abs, gr_mat_gr_poly_evaluate, gr_mat_hadamard, gr_mat_hessenberg, gr_mat_hessenberg_gauss, gr_mat_hessenberg_householder, gr_mat_hilbert, gr_mat_init, gr_mat_init_set, gr_mat_inv, gr_mat_invert_cols, gr_mat_invert_rows, gr_mat_is_diagonal, gr_mat_is_empty, gr_mat_is_hessenberg, gr_mat_is_lower_triangular, gr_mat_is_neg_one, gr_mat_is_one, gr_mat_is_scalar, gr_mat_is_square, gr_mat_is_upper_triangular, gr_mat_is_zero, gr_mat_jordan_blocks, gr_mat_jordan_form, gr_mat_jordan_transformation, gr_mat_log, gr_mat_log_jordan, gr_mat_lu, gr_mat_lu_classical, gr_mat_lu_recursive, gr_mat_minpoly_field, gr_mat_mul, gr_mat_mul_classical, gr_mat_mul_diag, gr_mat_mul_generic, gr_mat_mul_scalar, gr_mat_mul_strassen, gr_mat_neg, gr_mat_nonsingular_solve, gr_mat_nonsingular_solve_den, gr_mat_nonsingular_solve_den_fflu, gr_mat_nonsingular_solve_fflu, gr_mat_nonsingular_solve_fflu_precomp, gr_mat_nonsingular_solve_lu, gr_mat_nonsingular_solve_lu_precomp, gr_mat_nonsingular_solve_tril, gr_mat_nonsingular_solve_tril_classical, gr_mat_nonsingular_solve_tril_recursive, gr_mat_nonsingular_solve_triu, gr_mat_nonsingular_solve_triu_classical, gr_mat_nonsingular_solve_triu_recursive, gr_mat_nullspace, gr_mat_one, gr_mat_ones, gr_mat_pascal, gr_mat_print, gr_mat_randops, gr_mat_randpermdiag, gr_mat_randrank, gr_mat_randtest, gr_mat_rank, gr_mat_rank_fflu, gr_mat_rank_lu, gr_mat_reduce_row, gr_mat_rref, gr_mat_rref_den, gr_mat_rref_den_fflu, gr_mat_rref_fflu, gr_mat_rref_lu, gr_mat_set, gr_mat_set_fmpq, gr_mat_set_fmpq_mat, gr_mat_set_fmpz, gr_mat_set_fmpz_mat, gr_mat_set_jordan_blocks, gr_mat_set_scalar, gr_mat_set_si, gr_mat_set_ui, gr_mat_solve_field, gr_mat_sqr, gr_mat_stirling, gr_mat_sub, gr_mat_sub_scalar, gr_mat_submul_scalar, gr_mat_swap, gr_mat_swap_cols, gr_mat_swap_entrywise, gr_mat_swap_rows, gr_mat_trace, gr_mat_trace_prod2, gr_mat_transpose, gr_mat_transpose_resize, gr_mat_window_clear, gr_mat_window_init, gr_mat_write, gr_mat_zero, gr_method_tab_init, gr_modular_delta, gr_modular_j, gr_modular_lambda, gr_mpoly_add, gr_mpoly_assert_canonical, gr_mpoly_clear, gr_mpoly_combine_like_terms, gr_mpoly_equal, gr_mpoly_fit_bits, gr_mpoly_fit_length, gr_mpoly_fit_length_fit_bits, gr_mpoly_fit_length_reset_bits, gr_mpoly_gen, gr_mpoly_get_coeff_scalar_fmpz, gr_mpoly_get_coeff_scalar_ui, gr_mpoly_init, gr_mpoly_init2, gr_mpoly_init3, gr_mpoly_is_canonical, gr_mpoly_is_gen, gr_mpoly_is_one, gr_mpoly_is_zero, gr_mpoly_mul, gr_mpoly_mul_fmpq, gr_mpoly_mul_fmpz, gr_mpoly_mul_johnson, gr_mpoly_mul_monomial, gr_mpoly_mul_scalar, gr_mpoly_mul_si, gr_mpoly_mul_ui, gr_mpoly_neg, gr_mpoly_one, gr_mpoly_print_pretty, gr_mpoly_push_term_scalar_fmpz, gr_mpoly_push_term_scalar_ui, gr_mpoly_randtest_bits, gr_mpoly_randtest_bound, gr_mpoly_set, gr_mpoly_set_coeff_fmpq_fmpz, gr_mpoly_set_coeff_fmpq_ui, gr_mpoly_set_coeff_fmpz_fmpz, gr_mpoly_set_coeff_fmpz_ui, gr_mpoly_set_coeff_scalar_fmpz, gr_mpoly_set_coeff_scalar_ui, gr_mpoly_set_coeff_si_fmpz, gr_mpoly_set_coeff_si_ui, gr_mpoly_set_coeff_ui_fmpz, gr_mpoly_set_coeff_ui_ui, gr_mpoly_set_fmpq, gr_mpoly_set_fmpz, gr_mpoly_set_scalar, gr_mpoly_set_si, gr_mpoly_set_ui, gr_mpoly_sort_terms, gr_mpoly_sub, gr_mpoly_swap, gr_mpoly_write_pretty, gr_mpoly_zero, gr_mul, gr_mul_2exp_fmpz, gr_mul_2exp_si, gr_mul_fmpq, gr_mul_fmpz, gr_mul_other, gr_mul_si, gr_mul_two, gr_mul_ui, gr_neg, gr_neg_one, gr_nint, gr_not_equal, gr_not_implemented, gr_not_in_domain, gr_one, gr_other_add, gr_other_div, gr_other_divexact, gr_other_mul, gr_other_pow, gr_other_sub, gr_partitions_fmpz, gr_partitions_ui, gr_partitions_vec, gr_pi, gr_poly_acos_series, gr_poly_acosh_series, gr_poly_add, gr_poly_add_series, gr_poly_asin_series, gr_poly_asinh_series, gr_poly_atan_series, gr_poly_atanh_series, gr_poly_clear, gr_poly_compose, gr_poly_compose_divconquer, gr_poly_compose_horner, gr_poly_compose_series, gr_poly_compose_series_brent_kung, gr_poly_compose_series_divconquer, gr_poly_compose_series_horner, gr_poly_derivative, gr_poly_div, gr_poly_div_basecase, gr_poly_div_divconquer, gr_poly_div_newton, gr_poly_div_series, gr_poly_div_series_basecase, gr_poly_div_series_invmul, gr_poly_div_series_newton, gr_poly_divrem, gr_poly_divrem_basecase, gr_poly_divrem_divconquer, gr_poly_divrem_newton, gr_poly_entry_ptr, gr_poly_equal, gr_poly_evaluate, gr_poly_evaluate_horner, gr_poly_evaluate_other, gr_poly_evaluate_other_horner, gr_poly_evaluate_other_rectangular, gr_poly_evaluate_rectangular, gr_poly_evaluate_vec_fast, gr_poly_evaluate_vec_iter, gr_poly_exp_series, gr_poly_exp_series_basecase, gr_poly_exp_series_basecase_mul, gr_poly_exp_series_newton, gr_poly_factor_squarefree, gr_poly_fit_length, gr_poly_gcd, gr_poly_gcd_euclidean, gr_poly_gcd_hgcd, gr_poly_gen, gr_poly_get_coeff_scalar, gr_poly_init, gr_poly_init2, gr_poly_integral, gr_poly_inv, gr_poly_inv_series, gr_poly_inv_series_basecase, gr_poly_inv_series_newton, gr_poly_is_gen, gr_poly_is_monic, gr_poly_is_one, gr_poly_is_zero, gr_poly_length, gr_poly_log1p_series, gr_poly_log_series, gr_poly_make_monic, gr_poly_mul, gr_poly_mul_scalar, gr_poly_mullow, gr_poly_neg, gr_poly_neg_one, gr_poly_nth_derivative, gr_poly_one, gr_poly_pow_fmpz, gr_poly_pow_series_fmpq_recurrence, gr_poly_pow_series_ui, gr_poly_pow_series_ui_binexp, gr_poly_pow_ui, gr_poly_pow_ui_binexp, gr_poly_print, gr_poly_randtest, gr_poly_rem, gr_poly_resultant, gr_poly_resultant_euclidean, gr_poly_resultant_hgcd, gr_poly_resultant_small, gr_poly_resultant_sylvester, gr_poly_reverse, gr_poly_roots, gr_poly_roots_other, gr_poly_rsqrt_series, gr_poly_rsqrt_series_basecase, gr_poly_rsqrt_series_miller, gr_poly_rsqrt_series_newton, gr_poly_set, gr_poly_set_coeff_fmpq, gr_poly_set_coeff_fmpz, gr_poly_set_coeff_scalar, gr_poly_set_coeff_si, gr_poly_set_coeff_ui, gr_poly_set_fmpq, gr_poly_set_fmpq_poly, gr_poly_set_fmpz, gr_poly_set_fmpz_poly, gr_poly_set_gr_poly_other, gr_poly_set_scalar, gr_poly_set_si, gr_poly_set_ui, gr_poly_shift_left, gr_poly_shift_right, gr_poly_sin_cos_series_basecase, gr_poly_sin_cos_series_tangent, gr_poly_sqrt_series, gr_poly_sqrt_series_basecase, gr_poly_sqrt_series_miller, gr_poly_sqrt_series_newton, gr_poly_squarefree_part, gr_poly_sub, gr_poly_sub_series, gr_poly_swap, gr_poly_tan_series, gr_poly_tan_series_basecase, gr_poly_tan_series_newton, gr_poly_taylor_shift, gr_poly_taylor_shift_convolution, gr_poly_taylor_shift_divconquer, gr_poly_taylor_shift_horner, gr_poly_truncate, gr_poly_write, gr_poly_xgcd_euclidean, gr_poly_xgcd_hgcd, gr_poly_zero, gr_polygamma, gr_polylog, gr_pow, gr_pow_fmpq, gr_pow_fmpz, gr_pow_other, gr_pow_si, gr_pow_ui, gr_print, gr_println, gr_randtest, gr_randtest_not_zero, gr_randtest_small, gr_re, gr_rfac, gr_rfac_fmpz, gr_rfac_ui, gr_rfac_vec, gr_rgamma, gr_riemann_xi, gr_rising, gr_rising_ui, gr_rising_ui_forward, gr_rsqrt, gr_sec, gr_sec_pi, gr_sech, gr_series_acos, gr_series_acosh, gr_series_add, gr_series_agm1, gr_series_airy, gr_series_airy_ai, gr_series_airy_ai_prime, gr_series_airy_bi, gr_series_airy_bi_prime, gr_series_asin, gr_series_asinh, gr_series_atan, gr_series_atanh, gr_series_beta_lower, gr_series_clear, gr_series_cos_integral, gr_series_cosh_integral, gr_series_digamma, gr_series_dirichlet_hardy_theta, gr_series_dirichlet_hardy_z, gr_series_dirichlet_l, gr_series_div, gr_series_elliptic_k, gr_series_equal, gr_series_erf, gr_series_erfc, gr_series_erfi, gr_series_exp, gr_series_exp_integral_ei, gr_series_fresnel, gr_series_fresnel_c, gr_series_fresnel_s, gr_series_gamma, gr_series_gamma_lower, gr_series_gamma_upper, gr_series_gen, gr_series_hurwitz_zeta, gr_series_hypgeom_pfq, gr_series_init, gr_series_inv, gr_series_is_one, gr_series_is_zero, gr_series_jacobi_theta, gr_series_jacobi_theta_1, gr_series_jacobi_theta_2, gr_series_jacobi_theta_3, gr_series_jacobi_theta_4, gr_series_lgamma, gr_series_log, gr_series_log_integral, gr_series_make_exact, gr_series_mul, gr_series_neg, gr_series_one, gr_series_polylog, gr_series_randtest, gr_series_rgamma, gr_series_rsqrt, gr_series_set, gr_series_set_fmpq, gr_series_set_fmpz, gr_series_set_gr_poly, gr_series_set_scalar, gr_series_set_si, gr_series_set_ui, gr_series_sin_integral, gr_series_sinh_integral, gr_series_sqrt, gr_series_sub, gr_series_swap, gr_series_tan, gr_series_weierstrass_p, gr_series_write, gr_series_zero, gr_set, gr_set_d, gr_set_fmpq, gr_set_fmpz, gr_set_fmpz_2exp_fmpz, gr_set_other, gr_set_shallow, gr_set_si, gr_set_str, gr_set_ui, gr_sgn, gr_sin, gr_sin_cos, gr_sin_cos_pi, gr_sin_integral, gr_sin_pi, gr_sinc, gr_sinc_pi, gr_sinh, gr_sinh_cosh, gr_sinh_integral, gr_spherical_y_si, gr_sqr, gr_sqrt, gr_stieltjes, gr_stirling_s1_ui_vec, gr_stirling_s1_uiui, gr_stirling_s1u_ui_vec, gr_stirling_s1u_uiui, gr_stirling_s2_ui_vec, gr_stirling_s2_uiui, gr_stream_init_file, gr_stream_init_str, gr_stream_write, gr_stream_write_fmpz, gr_stream_write_free, gr_stream_write_si, gr_stream_write_ui, gr_sub, gr_sub_fmpq, gr_sub_fmpz, gr_sub_other, gr_sub_si, gr_sub_ui, gr_submul, gr_submul_fmpq, gr_submul_fmpz, gr_submul_other, gr_submul_si, gr_submul_ui, gr_swap, gr_swap2, gr_tan, gr_tan_pi, gr_tanh, gr_test_add_aliasing, gr_test_add_associative, gr_test_add_commutative, gr_test_add_type_variants, gr_test_addmul_submul, gr_test_addmul_type_variants, gr_test_binary_op_aliasing, gr_test_binary_op_associative, gr_test_binary_op_commutative, gr_test_binary_op_left_distributive, gr_test_binary_op_right_distributive, gr_test_binary_op_type_variants, gr_test_complex_parts, gr_test_div_right_distributive, gr_test_div_then_mul, gr_test_div_type_variants, gr_test_divexact, gr_test_divexact_type_variants, gr_test_equal, gr_test_field, gr_test_get_fmpq, gr_test_get_fmpz, gr_test_get_fmpz_2exp_fmpz, gr_test_get_si, gr_test_get_ui, gr_test_init_clear, gr_test_integral_domain, gr_test_inv_involution, gr_test_inv_multiplication, gr_test_iter, gr_test_mat_mul_classical_associative, gr_test_mul_2exp_fmpz, gr_test_mul_2exp_si, gr_test_mul_aliasing, gr_test_mul_associative, gr_test_mul_commutative, gr_test_mul_left_distributive, gr_test_mul_right_distributive, gr_test_mul_then_div, gr_test_mul_type_variants, gr_test_multiplicative_group, gr_test_neg, gr_test_one, gr_test_ordered_ring_cmp, gr_test_ordered_ring_cmpabs, gr_test_pow_fmpz_exponent_addition, gr_test_pow_ui_aliasing, gr_test_pow_ui_base_multiplication, gr_test_pow_ui_base_scalar_multiplication, gr_test_pow_ui_exponent_addition, gr_test_randtest_not_zero, gr_test_ring, gr_test_rsqrt, gr_test_set_fmpq, gr_test_set_fmpz, gr_test_set_si, gr_test_set_ui, gr_test_sqrt, gr_test_sub_aliasing, gr_test_sub_equal_neg_add, gr_test_sub_type_variants, gr_test_submul_type_variants, gr_test_swap, gr_test_vec_add, gr_test_vec_binary_op, gr_test_vec_div, gr_test_vec_divexact, gr_test_vec_dot, gr_test_vec_mul, gr_test_vec_pow, gr_test_vec_sub, gr_test_zero_one, gr_trunc, gr_vec_append, gr_vec_clear, gr_vec_entry_ptr, gr_vec_entry_srcptr, gr_vec_fit_length, gr_vec_init, gr_vec_length, gr_vec_print, gr_vec_set, gr_vec_set_length, gr_vec_write, gr_weierstrass_p, gr_weierstrass_p_inv, gr_weierstrass_p_prime, gr_weierstrass_sigma, gr_weierstrass_zeta, gr_write, gr_write_n, gr_zero, gr_zeta, gr_zeta_nzeros, gr_zeta_ui, gr_zeta_zero, gr_zeta_zero_vec`` * ``qqbar_set_fmpzi`` List of removals diff --git a/src/gr.h b/src/gr.h index ce8cc8a301..4087e178b5 100644 --- a/src/gr.h +++ b/src/gr.h @@ -704,7 +704,7 @@ void gr_method_tab_init(gr_funcptr * methods, gr_method_tab_input * tab); typedef enum { GR_CTX_FMPZ, GR_CTX_FMPQ, GR_CTX_FMPZI, - GR_CTX_FMPZ_MOD, GR_CTX_NMOD, GR_CTX_NMOD8, + GR_CTX_FMPZ_MOD, GR_CTX_NMOD, GR_CTX_NMOD8, GR_CTX_NMOD32, GR_CTX_FQ, GR_CTX_FQ_NMOD, GR_CTX_FQ_ZECH, GR_CTX_NF, GR_CTX_REAL_ALGEBRAIC_QQBAR, GR_CTX_COMPLEX_ALGEBRAIC_QQBAR, @@ -1339,7 +1339,9 @@ void gr_ctx_fmpz_mod_set_primality(gr_ctx_t ctx, truth_t is_prime); void gr_ctx_init_nmod(gr_ctx_t ctx, ulong n); void _gr_ctx_init_nmod(gr_ctx_t ctx, void * nmod_t_ref); + void gr_ctx_init_nmod8(gr_ctx_t ctx, unsigned char n); +void gr_ctx_init_nmod32(gr_ctx_t ctx, unsigned int n); void gr_ctx_init_real_qqbar(gr_ctx_t ctx); void gr_ctx_init_complex_qqbar(gr_ctx_t ctx); diff --git a/src/gr/init_random.c b/src/gr/init_random.c index 5a3ea345a0..d1ae72da4d 100644 --- a/src/gr/init_random.c +++ b/src/gr/init_random.c @@ -24,6 +24,8 @@ void gr_ctx_init_random(gr_ctx_t ctx, flint_rand_t state) gr_ctx_init_fmpz(ctx); else if (which < 40) gr_ctx_init_nmod8(ctx, n_randtest(state) % 255 + 1); + else if (which < 42) + gr_ctx_init_nmod32(ctx, n_randtest(state) % UWORD(4294967295) + 1); else if (which < 45) gr_ctx_init_nmod(ctx, n_randtest_not_zero(state)); else if (which < 50) diff --git a/src/gr/nmod32.c b/src/gr/nmod32.c new file mode 100644 index 0000000000..d27745411e --- /dev/null +++ b/src/gr/nmod32.c @@ -0,0 +1,459 @@ +/* + Copyright (C) 2023 Fredrik Johansson + + This file is part of FLINT. + + FLINT is free software: you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License (LGPL) as published + by the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. See . +*/ + +#include "fmpz.h" +#include "fmpq.h" +#include "nmod.h" +#include "nmod_vec.h" +#include "gr.h" +#include "gr_mat.h" + +#define NMOD32_CTX_REF(ring_ctx) (((nmod_t *)((ring_ctx)))) +#define NMOD32_CTX(ring_ctx) (*NMOD32_CTX_REF(ring_ctx)) + +typedef unsigned int nmod32_struct; +typedef nmod32_struct nmod32_t[1]; + +void +nmod32_ctx_write(gr_stream_t out, gr_ctx_t ctx) +{ + gr_stream_write(out, "Integers mod "); + gr_stream_write_ui(out, NMOD32_CTX(ctx).n); + gr_stream_write(out, " (nmod32)"); +} + +/* we don't want to call n_is_prime because this predicate should + be fast. allow storing a flag in the context object? */ +truth_t +nmod32_ctx_is_field(const gr_ctx_t ctx) +{ + return T_UNKNOWN; +} + +void +nmod32_init(nmod32_t x, const gr_ctx_t ctx) +{ + x[0] = 0; +} + +void +nmod32_clear(nmod32_t x, const gr_ctx_t ctx) +{ +} + +void +nmod32_swap(nmod32_t x, nmod32_t y, const gr_ctx_t ctx) +{ + nmod32_t t; + *t = *x; + *x = *y; + *y = *t; +} + +void +nmod32_set_shallow(nmod32_t res, const nmod32_t x, const gr_ctx_t ctx) +{ + *res = *x; +} + +int +nmod32_randtest(nmod32_t res, flint_rand_t state, const gr_ctx_t ctx) +{ + res[0] = n_randtest(state) % NMOD32_CTX(ctx).n; + return GR_SUCCESS; +} + +int +nmod32_write(gr_stream_t out, const nmod32_t x, const gr_ctx_t ctx) +{ + gr_stream_write_si(out, x[0]); + return GR_SUCCESS; +} + +int +nmod32_zero(nmod32_t x, const gr_ctx_t ctx) +{ + x[0] = 0; + return GR_SUCCESS; +} + +int +nmod32_one(nmod32_t x, const gr_ctx_t ctx) +{ + x[0] = (NMOD32_CTX(ctx).n != 1); + return GR_SUCCESS; +} + +int +nmod32_set_si(nmod32_t res, slong v, const gr_ctx_t ctx) +{ + ulong t; + nmod_t mod = NMOD32_CTX(ctx); + t = FLINT_ABS(v); + NMOD_RED(t, t, mod); + if (v < 0) + t = nmod_neg(t, mod); + res[0] = t; + return GR_SUCCESS; +} + +int +nmod32_set_ui(nmod32_t res, ulong v, const gr_ctx_t ctx) +{ + ulong t; + nmod_t mod = NMOD32_CTX(ctx); + NMOD_RED(t, v, mod); + res[0] = t; + return GR_SUCCESS; +} + +int +nmod32_set_fmpz(nmod32_t res, const fmpz_t v, const gr_ctx_t ctx) +{ + nmod_t mod = NMOD32_CTX(ctx); + res[0] = fmpz_get_nmod(v, mod); + return GR_SUCCESS; +} + +truth_t +nmod32_is_zero(const nmod32_t x, const gr_ctx_t ctx) +{ + return (x[0] == 0) ? T_TRUE : T_FALSE; +} + +truth_t +nmod32_is_one(const nmod32_t x, const gr_ctx_t ctx) +{ + return (x[0] == (NMOD32_CTX(ctx).n != 1)) ? T_TRUE : T_FALSE; +} + +truth_t +nmod32_is_neg_one(const nmod32_t x, const gr_ctx_t ctx) +{ + return (x[0] == NMOD32_CTX(ctx).n - 1) ? T_TRUE : T_FALSE; +} + +truth_t +nmod32_equal(const nmod32_t x, const nmod32_t y, const gr_ctx_t ctx) +{ + return (x[0] == y[0]) ? T_TRUE : T_FALSE; +} + +int +nmod32_set(nmod32_t res, const nmod32_t x, const gr_ctx_t ctx) +{ + res[0] = x[0]; + return GR_SUCCESS; +} + +int +nmod32_neg(nmod32_t res, const nmod32_t x, const gr_ctx_t ctx) +{ + res[0] = nmod_neg(x[0], NMOD32_CTX(ctx)); + return GR_SUCCESS; +} + +int +nmod32_add(nmod32_t res, const nmod32_t x, const nmod32_t y, const gr_ctx_t ctx) +{ + res[0] = nmod_add(x[0], y[0], NMOD32_CTX(ctx)); + return GR_SUCCESS; +} + +int +nmod32_add_si(nmod32_t res, const nmod32_t x, slong y, const gr_ctx_t ctx) +{ + nmod32_t t; + nmod32_set_si(t, y, ctx); + return nmod32_add(res, x, t, ctx); +} + +int +nmod32_sub(nmod32_t res, const nmod32_t x, const nmod32_t y, const gr_ctx_t ctx) +{ + res[0] = nmod_sub(x[0], y[0], NMOD32_CTX(ctx)); + return GR_SUCCESS; +} + +int +nmod32_mul(nmod32_t res, const nmod32_t x, const nmod32_t y, const gr_ctx_t ctx) +{ + res[0] = nmod_mul(x[0], y[0], NMOD32_CTX(ctx)); + return GR_SUCCESS; +} + +int +nmod32_mul_si(nmod32_t res, const nmod32_t x, slong y, const gr_ctx_t ctx) +{ + nmod32_t t; + nmod32_set_si(t, y, ctx); + return nmod32_mul(res, x, t, ctx); +} + +int +nmod32_addmul(nmod32_t res, const nmod32_t x, const nmod32_t y, const gr_ctx_t ctx) +{ + ulong r = res[0]; + NMOD_ADDMUL(r, x[0], y[0], NMOD32_CTX(ctx)); + res[0] = r; + return GR_SUCCESS; +} + +int +nmod32_submul(nmod32_t res, const nmod32_t x, const nmod32_t y, const gr_ctx_t ctx) +{ + ulong r = res[0]; + ulong t = nmod_neg(y[0], NMOD32_CTX(ctx)); + NMOD_ADDMUL(r, x[0], t, NMOD32_CTX(ctx)); + res[0] = r; + return GR_SUCCESS; +} + +int +nmod32_mul_two(nmod32_t res, const nmod32_t x, const gr_ctx_t ctx) +{ + return nmod32_add(res, x, x, ctx); +} + +int +nmod32_sqr(nmod32_t res, const nmod32_t x, const gr_ctx_t ctx) +{ + return nmod32_mul(res, x, x, ctx); +} + +int +nmod32_inv(nmod32_t res, const nmod32_t x, const gr_ctx_t ctx) +{ + ulong r, g; + + /* todo: also handle -1 fast? */ + if (x[0] == 1) + { + res[0] = x[0]; + return GR_SUCCESS; + } + + g = n_gcdinv(&r, x[0], NMOD32_CTX(ctx).n); + if (g == 1) + { + res[0] = r; + return GR_SUCCESS; + } + else + { + res[0] = 0; + return GR_DOMAIN; + } +} + +int +nmod32_div(nmod32_t res, const nmod32_t x, const nmod32_t y, const gr_ctx_t ctx) +{ + nmod32_t t; + int status; + + status = nmod32_inv(t, y, ctx); + nmod32_mul(res, x, t, ctx); + return status; +} + +int +nmod32_div_si(nmod32_t res, const nmod32_t x, slong y, const gr_ctx_t ctx) +{ + nmod32_t t; + nmod32_set_si(t, y, ctx); + return nmod32_div(res, x, t, ctx); +} + +truth_t +nmod32_is_invertible(const nmod32_t x, const gr_ctx_t ctx) +{ + ulong r, g; + g = n_gcdinv(&r, x[0], NMOD32_CTX(ctx).n); + return (g == 1) ? T_TRUE : T_FALSE; +} + +/* todo: overflow checks */ +int +_nmod32_vec_dot(nmod32_t res, const nmod32_t initial, int subtract, const nmod32_struct * vec1, const nmod32_struct * vec2, slong len, gr_ctx_t ctx) +{ + slong i; + ulong n, s; + + if (len <= 0) + { + if (initial == NULL) + nmod32_zero(res, ctx); + else + nmod32_set(res, initial, ctx); + return GR_SUCCESS; + } + + n = NMOD32_CTX(ctx).n; + + if (initial == NULL) + { + s = 0; + } + else + { + if (subtract) + s = (n - initial[0]); + else + s = initial[0]; + } + + { + ulong ss; + int nlimbs; + + nlimbs = _nmod_vec_dot_bound_limbs(len, NMOD32_CTX(ctx)); + NMOD_VEC_DOT(ss, i, len, (ulong) vec1[i], (ulong) vec2[i], NMOD32_CTX(ctx), nlimbs); + s = n_addmod(s, ss, n); + } + + nmod32_set_ui(res, s, ctx); + + if (subtract && res[0] != 0) + res[0] = (n - res[0]); + + return GR_SUCCESS; +} + +/* todo: overflow checks */ +int +_nmod32_vec_dot_rev(nmod32_t res, const nmod32_t initial, int subtract, const nmod32_struct * vec1, const nmod32_struct * vec2, slong len, gr_ctx_t ctx) +{ + slong i; + ulong n, s; + + if (len <= 0) + { + if (initial == NULL) + nmod32_zero(res, ctx); + else + nmod32_set(res, initial, ctx); + return GR_SUCCESS; + } + + n = NMOD32_CTX(ctx).n; + + if (initial == NULL) + { + s = 0; + } + else + { + if (subtract) + s = (n - initial[0]); + else + s = initial[0]; + } + + { + ulong ss; + int nlimbs; + + nlimbs = _nmod_vec_dot_bound_limbs(len, NMOD32_CTX(ctx)); + NMOD_VEC_DOT(ss, i, len, (ulong) vec1[i], (ulong) vec2[len - 1 - i], NMOD32_CTX(ctx), nlimbs); + s = n_addmod(s, ss, n); + } + + nmod32_set_ui(res, s, ctx); + + if (subtract && res[0] != 0) + res[0] = (n - res[0]); + + return GR_SUCCESS; +} + +/* todo: tuning for rectangular matrices */ +int +_nmod32_mat_mul(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, gr_ctx_t ctx) +{ + if (A->r >= 256 && A->c >= 256 && B->c >= 256) + return gr_mat_mul_strassen(C, A, B, ctx); + else + return gr_mat_mul_classical(C, A, B, ctx); +} + + +int _nmod32_methods_initialized = 0; + +gr_static_method_table _nmod32_methods; + +gr_method_tab_input _nmod32_methods_input[] = +{ + {GR_METHOD_CTX_WRITE, (gr_funcptr) nmod32_ctx_write}, + {GR_METHOD_CTX_IS_RING, (gr_funcptr) gr_generic_ctx_predicate_true}, + {GR_METHOD_CTX_IS_COMMUTATIVE_RING, (gr_funcptr) gr_generic_ctx_predicate_true}, + {GR_METHOD_CTX_IS_INTEGRAL_DOMAIN, (gr_funcptr) nmod32_ctx_is_field}, + {GR_METHOD_CTX_IS_FIELD, (gr_funcptr) nmod32_ctx_is_field}, + {GR_METHOD_CTX_IS_FINITE, + (gr_funcptr) gr_generic_ctx_predicate_true}, + {GR_METHOD_CTX_IS_FINITE_CHARACTERISTIC, + (gr_funcptr) gr_generic_ctx_predicate_true}, + {GR_METHOD_CTX_IS_EXACT, (gr_funcptr) gr_generic_ctx_predicate_true}, + {GR_METHOD_CTX_IS_CANONICAL, + (gr_funcptr) gr_generic_ctx_predicate_true}, + {GR_METHOD_INIT, (gr_funcptr) nmod32_init}, + {GR_METHOD_CLEAR, (gr_funcptr) nmod32_clear}, + {GR_METHOD_SWAP, (gr_funcptr) nmod32_swap}, + {GR_METHOD_SET_SHALLOW, (gr_funcptr) nmod32_set_shallow}, + {GR_METHOD_RANDTEST, (gr_funcptr) nmod32_randtest}, + {GR_METHOD_WRITE, (gr_funcptr) nmod32_write}, + {GR_METHOD_ZERO, (gr_funcptr) nmod32_zero}, + {GR_METHOD_ONE, (gr_funcptr) nmod32_one}, + {GR_METHOD_IS_ZERO, (gr_funcptr) nmod32_is_zero}, + {GR_METHOD_IS_ONE, (gr_funcptr) nmod32_is_one}, + {GR_METHOD_IS_NEG_ONE, (gr_funcptr) nmod32_is_neg_one}, + {GR_METHOD_EQUAL, (gr_funcptr) nmod32_equal}, + {GR_METHOD_SET, (gr_funcptr) nmod32_set}, + {GR_METHOD_SET_SI, (gr_funcptr) nmod32_set_si}, + {GR_METHOD_SET_UI, (gr_funcptr) nmod32_set_ui}, + {GR_METHOD_SET_FMPZ, (gr_funcptr) nmod32_set_fmpz}, + {GR_METHOD_NEG, (gr_funcptr) nmod32_neg}, + {GR_METHOD_ADD, (gr_funcptr) nmod32_add}, + {GR_METHOD_ADD_SI, (gr_funcptr) nmod32_add_si}, + {GR_METHOD_SUB, (gr_funcptr) nmod32_sub}, + {GR_METHOD_MUL, (gr_funcptr) nmod32_mul}, + {GR_METHOD_MUL_SI, (gr_funcptr) nmod32_mul_si}, + {GR_METHOD_ADDMUL, (gr_funcptr) nmod32_addmul}, + {GR_METHOD_SUBMUL, (gr_funcptr) nmod32_submul}, + {GR_METHOD_MUL_TWO, (gr_funcptr) nmod32_mul_two}, + {GR_METHOD_SQR, (gr_funcptr) nmod32_sqr}, + {GR_METHOD_DIV, (gr_funcptr) nmod32_div}, + {GR_METHOD_DIV_SI, (gr_funcptr) nmod32_div_si}, + {GR_METHOD_IS_INVERTIBLE, (gr_funcptr) nmod32_is_invertible}, + {GR_METHOD_INV, (gr_funcptr) nmod32_inv}, + {GR_METHOD_VEC_DOT, (gr_funcptr) _nmod32_vec_dot}, + {GR_METHOD_VEC_DOT_REV, (gr_funcptr) _nmod32_vec_dot_rev}, + {GR_METHOD_MAT_MUL, (gr_funcptr) _nmod32_mat_mul}, + {0, (gr_funcptr) NULL}, +}; + +void +gr_ctx_init_nmod32(gr_ctx_t ctx, unsigned int n) +{ + ctx->which_ring = GR_CTX_NMOD32; + ctx->sizeof_elem = sizeof(nmod32_struct); + ctx->size_limit = WORD_MAX; + + nmod_init(NMOD32_CTX_REF(ctx), n); + + ctx->methods = _nmod32_methods; + + if (!_nmod32_methods_initialized) + { + gr_method_tab_init(_nmod32_methods, _nmod32_methods_input); + _nmod32_methods_initialized = 1; + } +} diff --git a/src/gr/nmod8.c b/src/gr/nmod8.c index d394008835..0e6260a1b0 100644 --- a/src/gr/nmod8.c +++ b/src/gr/nmod8.c @@ -310,16 +310,32 @@ _nmod8_vec_dot(nmod8_t res, const nmod8_t initial, int subtract, const nmod8_str s = initial[0]; } - for (i = 0; i + 4 < len; i += 4) + if (len < 65536) { - s += (ulong) vec1[i ] * (ulong) vec2[i]; - s += (ulong) vec1[i + 1] * (ulong) vec2[i + 1]; - s += (ulong) vec1[i + 2] * (ulong) vec2[i + 2]; - s += (ulong) vec1[i + 3] * (ulong) vec2[i + 3]; + unsigned int ss = 0; + + for (i = 0; i + 4 < len; i += 4) + { + s += (unsigned int) vec1[i + 0] * (unsigned int) vec2[i + 0]; + s += (unsigned int) vec1[i + 1] * (unsigned int) vec2[i + 1]; + s += (unsigned int) vec1[i + 2] * (unsigned int) vec2[i + 2]; + s += (unsigned int) vec1[i + 3] * (unsigned int) vec2[i + 3]; + } + + for ( ; i < len; i++) + s += (unsigned int) vec1[i] * (unsigned int) vec2[i]; + + s += ss; } + else + { + ulong ss; + int nlimbs; - for ( ; i < len; i++) - s += (ulong) vec1[i] * (ulong) vec2[i]; + nlimbs = _nmod_vec_dot_bound_limbs(len, NMOD8_CTX(ctx)); + NMOD_VEC_DOT(ss, i, len, (ulong) vec1[i], (ulong) vec2[i], NMOD8_CTX(ctx), nlimbs); + s = n_addmod(s, ss, n); + } nmod8_set_ui(res, s, ctx); @@ -359,16 +375,32 @@ _nmod8_vec_dot_rev(nmod8_t res, const nmod8_t initial, int subtract, const nmod8 s = initial[0]; } - for (i = 0; i + 4 < len; i += 4) + if (len < 65536) { - s += (ulong) vec1[i ] * (ulong) vec2[len - 1 - i]; - s += (ulong) vec1[i + 1] * (ulong) vec2[len - 1 - i - 1]; - s += (ulong) vec1[i + 2] * (ulong) vec2[len - 1 - i - 2]; - s += (ulong) vec1[i + 3] * (ulong) vec2[len - 1 - i - 3]; + unsigned int ss = 0; + + for (i = 0; i + 4 < len; i += 4) + { + s += (unsigned int) vec1[i + 0] * (unsigned int) vec2[len - 1 - i - 0]; + s += (unsigned int) vec1[i + 1] * (unsigned int) vec2[len - 1 - i - 1]; + s += (unsigned int) vec1[i + 2] * (unsigned int) vec2[len - 1 - i - 2]; + s += (unsigned int) vec1[i + 3] * (unsigned int) vec2[len - 1 - i - 3]; + } + + for ( ; i < len; i++) + s += (unsigned int) vec1[i] * (unsigned int) vec2[len - 1 - i]; + + s += ss; } + else + { + ulong ss; + int nlimbs; - for ( ; i < len; i++) - s += (ulong) vec1[i] * (ulong) vec2[len - 1 - i]; + nlimbs = _nmod_vec_dot_bound_limbs(len, NMOD8_CTX(ctx)); + NMOD_VEC_DOT(ss, i, len, (ulong) vec1[i], (ulong) vec2[len - 1 - i], NMOD8_CTX(ctx), nlimbs); + s = n_addmod(s, ss, n); + } nmod8_set_ui(res, s, ctx); diff --git a/src/gr/test/t-nmod32.c b/src/gr/test/t-nmod32.c new file mode 100644 index 0000000000..17a3aff726 --- /dev/null +++ b/src/gr/test/t-nmod32.c @@ -0,0 +1,39 @@ +#include "gr.h" + +int main(void) +{ + gr_ctx_t ZZn; + int flags = GR_TEST_ALWAYS_ABLE; + ulong n; + int i; + flint_rand_t state; + + flint_randinit(state); + + flint_printf("nmod32...."); + fflush(stdout); + + for (i = 0; i < 100; i++) + { + n = (unsigned int) n_randtest(state); + if (n == 0) + n = 1; + gr_ctx_init_nmod32(ZZn, n); + gr_test_ring(ZZn, 100, flags); + gr_ctx_clear(ZZn); + } + + gr_ctx_init_nmod32(ZZn, UWORD(4294967291)); + gr_test_ring(ZZn, 10000, flags); + gr_ctx_clear(ZZn); + + gr_ctx_init_nmod32(ZZn, UWORD(4294967295)); + gr_test_ring(ZZn, 10000, flags); + gr_ctx_clear(ZZn); + + flint_randclear(state); + + flint_cleanup(); + flint_printf(" PASS\n"); + return 0; +} diff --git a/src/gr_mat.h b/src/gr_mat.h index 2b297681d0..5fefdf86f3 100644 --- a/src/gr_mat.h +++ b/src/gr_mat.h @@ -146,6 +146,7 @@ WARN_UNUSED_RESULT int gr_mat_submul_scalar(gr_mat_t res, const gr_mat_t mat, gr WARN_UNUSED_RESULT int gr_mat_div_scalar(gr_mat_t res, const gr_mat_t mat, gr_srcptr x, gr_ctx_t ctx); WARN_UNUSED_RESULT int gr_mat_mul_classical(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, gr_ctx_t ctx); +WARN_UNUSED_RESULT int gr_mat_mul_strassen(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, gr_ctx_t ctx); WARN_UNUSED_RESULT int gr_mat_mul_generic(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, gr_ctx_t ctx); WARN_UNUSED_RESULT int gr_mat_mul(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, gr_ctx_t ctx); diff --git a/src/gr_mat/mul_strassen.c b/src/gr_mat/mul_strassen.c new file mode 100644 index 0000000000..deefd34f2a --- /dev/null +++ b/src/gr_mat/mul_strassen.c @@ -0,0 +1,176 @@ +/* + Copyright (C) 2008, Martin Albrecht + Copyright (C) 2008, 2009 William Hart + Copyright (C) 2010, 2023 Fredrik Johansson + + This file is part of FLINT. + + FLINT is free software: you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License (LGPL) as published + by the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. See . +*/ + +#include "gr_mat.h" + +#include "fmpz_mat.h" + +/* todo: optimize for small matrices */ +/* todo: bodrato squaring */ +/* todo: use fused add-mul operations when supported by + the matrix interface in the future */ + +int gr_mat_mul_strassen(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, gr_ctx_t ctx) +{ + slong ar, ac, br, bc; + slong anr, anc, bnr, bnc; + int status = GR_SUCCESS; + + gr_mat_t A11, A12, A21, A22; + gr_mat_t B11, B12, B21, B22; + gr_mat_t C11, C12, C21, C22; + gr_mat_t X1, X2; + + ar = A->r; + ac = A->c; + br = B->r; + bc = B->c; + + if (ar <= 1 || ac <= 1 || bc <= 1) + { + return gr_mat_mul_classical(C, A, B, ctx); + } + + if (ac != br || ar != C->r || bc != C->c) + { + return GR_DOMAIN; + } + + if (A == C || B == C) + { + gr_mat_t T; + gr_mat_init(T, ar, bc, ctx); + status |= gr_mat_mul_strassen(T, A, B, ctx); + status |= gr_mat_swap_entrywise(T, C, ctx); + gr_mat_clear(T, ctx); + return status; + } + + anr = ar / 2; + anc = ac / 2; + bnr = anc; + bnc = bc / 2; + + gr_mat_window_init(A11, A, 0, 0, anr, anc, ctx); + gr_mat_window_init(A12, A, 0, anc, anr, 2 * anc, ctx); + gr_mat_window_init(A21, A, anr, 0, 2 * anr, anc, ctx); + gr_mat_window_init(A22, A, anr, anc, 2 * anr, 2 * anc, ctx); + + gr_mat_window_init(B11, B, 0, 0, bnr, bnc, ctx); + gr_mat_window_init(B12, B, 0, bnc, bnr, 2 * bnc, ctx); + gr_mat_window_init(B21, B, bnr, 0, 2 * bnr, bnc, ctx); + gr_mat_window_init(B22, B, bnr, bnc, 2 * bnr, 2 * bnc, ctx); + + gr_mat_window_init(C11, C, 0, 0, anr, bnc, ctx); + gr_mat_window_init(C12, C, 0, bnc, anr, 2 * bnc, ctx); + gr_mat_window_init(C21, C, anr, 0, 2 * anr, bnc, ctx); + gr_mat_window_init(C22, C, anr, bnc, 2 * anr, 2 * bnc, ctx); + + gr_mat_init(X1, anr, FLINT_MAX(bnc, anc), ctx); + gr_mat_init(X2, anc, bnc, ctx); + + X1->c = anc; + + status |= gr_mat_sub(X1, A11, A21, ctx); + status |= gr_mat_sub(X2, B22, B12, ctx); + status |= gr_mat_mul(C21, X1, X2, ctx); + + status |= gr_mat_add(X1, A21, A22, ctx); + status |= gr_mat_sub(X2, B12, B11, ctx); + status |= gr_mat_mul(C22, X1, X2, ctx); + + status |= gr_mat_sub(X1, X1, A11, ctx); + status |= gr_mat_sub(X2, B22, X2, ctx); + status |= gr_mat_mul(C12, X1, X2, ctx); + + status |= gr_mat_sub(X1, A12, X1, ctx); + status |= gr_mat_mul(C11, X1, B22, ctx); + + X1->c = bnc; + status |= gr_mat_mul(X1, A11, B11, ctx); + status |= gr_mat_add(C12, X1, C12, ctx); + status |= gr_mat_add(C21, C12, C21, ctx); + status |= gr_mat_add(C12, C12, C22, ctx); + status |= gr_mat_add(C22, C21, C22, ctx); + status |= gr_mat_add(C12, C12, C11, ctx); + status |= gr_mat_sub(X2, X2, B21, ctx); + status |= gr_mat_mul(C11, A22, X2, ctx); + + gr_mat_clear(X2, ctx); + + status |= gr_mat_sub(C21, C21, C11, ctx); + status |= gr_mat_mul(C11, A12, B21, ctx); + + status |= gr_mat_add(C11, X1, C11, ctx); + + X1->c = FLINT_MAX(bnc, anc); + gr_mat_clear(X1, ctx); + + gr_mat_window_clear(A11, ctx); + gr_mat_window_clear(A12, ctx); + gr_mat_window_clear(A21, ctx); + gr_mat_window_clear(A22, ctx); + + gr_mat_window_clear(B11, ctx); + gr_mat_window_clear(B12, ctx); + gr_mat_window_clear(B21, ctx); + gr_mat_window_clear(B22, ctx); + + gr_mat_window_clear(C11, ctx); + gr_mat_window_clear(C12, ctx); + gr_mat_window_clear(C21, ctx); + gr_mat_window_clear(C22, ctx); + + if (bc > 2 * bnc) + { + gr_mat_t Bc, Cc; + gr_mat_window_init(Bc, B, 0, 2 * bnc, ac, bc, ctx); + gr_mat_window_init(Cc, C, 0, 2 * bnc, ar, bc, ctx); + status |= gr_mat_mul(Cc, A, Bc, ctx); + gr_mat_window_clear(Bc, ctx); + gr_mat_window_clear(Cc, ctx); + } + + if (ar > 2 * anr) + { + gr_mat_t Ar, Cr; + gr_mat_window_init(Ar, A, 2 * anr, 0, ar, ac, ctx); + gr_mat_window_init(Cr, C, 2 * anr, 0, ar, bc, ctx); + status |= gr_mat_mul(Cr, Ar, B, ctx); + gr_mat_window_clear(Ar, ctx); + gr_mat_window_clear(Cr, ctx); + } + + if (ac > 2 * anc) + { + gr_mat_t Ac, Br, Cb, tmp; + slong mt, nt; + + gr_mat_window_init(Ac, A, 0, 2 * anc, 2 * anr, ac, ctx); + gr_mat_window_init(Br, B, 2 * bnr, 0, ac, 2 * bnc, ctx); + gr_mat_window_init(Cb, C, 0, 0, 2 * anr, 2 * bnc, ctx); + + mt = Ac->r; + nt = Br->c; + + gr_mat_init(tmp, mt, nt, ctx); + status |= gr_mat_mul(tmp, Ac, Br, ctx); + status |= gr_mat_add(Cb, Cb, tmp, ctx); + gr_mat_clear(tmp, ctx); + gr_mat_window_clear(Ac, ctx); + gr_mat_window_clear(Br, ctx); + gr_mat_window_clear(Cb, ctx); + } + + return status; +} diff --git a/src/gr_mat/test/t-mul_strassen.c b/src/gr_mat/test/t-mul_strassen.c new file mode 100644 index 0000000000..46b7c88449 --- /dev/null +++ b/src/gr_mat/test/t-mul_strassen.c @@ -0,0 +1,80 @@ +#include "ulong_extras.h" +#include "gr_mat.h" + +int main(void) +{ + slong iter; + flint_rand_t state; + + flint_printf("mul_strassen..."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 1000; iter++) + { + gr_ctx_t ctx; + gr_mat_t A, B, C, D; + slong a, b, c; + int status = GR_SUCCESS; + + if (n_randint(state, 2)) + gr_ctx_init_fmpz(ctx); + else + gr_ctx_init_nmod(ctx, n_randtest_not_zero(state)); + + a = n_randint(state, 8); + b = n_randint(state, 8); + c = n_randint(state, 8); + + gr_mat_init(A, a, b, ctx); + gr_mat_init(B, b, c, ctx); + gr_mat_init(C, a, c, ctx); + gr_mat_init(D, a, c, ctx); + + status |= gr_mat_randtest(A, state, ctx); + status |= gr_mat_randtest(B, state, ctx); + status |= gr_mat_randtest(C, state, ctx); + status |= gr_mat_randtest(D, state, ctx); + + if (b == c && n_randint(state, 2)) + { + status |= gr_mat_set(C, A, ctx); + status |= gr_mat_mul_strassen(C, C, B, ctx); + } + else if (a == b && n_randint(state, 2)) + { + status |= gr_mat_set(C, B, ctx); + status |= gr_mat_mul_strassen(C, A, C, ctx); + } + else + { + status |= gr_mat_mul_strassen(C, A, B, ctx); + } + + status |= gr_mat_mul_classical(D, A, B, ctx); + + if (status != GR_SUCCESS && gr_mat_equal(C, D, ctx) == T_FALSE) + { + flint_printf("FAIL:\n"); + gr_ctx_println(ctx); + flint_printf("A:\n"); gr_mat_print(A, ctx); flint_printf("\n\n"); + flint_printf("B:\n"); gr_mat_print(B, ctx); flint_printf("\n\n"); + flint_printf("C:\n"); gr_mat_print(C, ctx); flint_printf("\n\n"); + flint_printf("D:\n"); gr_mat_print(D, ctx); flint_printf("\n\n"); + flint_abort(); + } + + gr_mat_clear(A, ctx); + gr_mat_clear(B, ctx); + gr_mat_clear(C, ctx); + gr_mat_clear(D, ctx); + + gr_ctx_clear(ctx); + } + + flint_randclear(state); + flint_cleanup(); + flint_printf("PASS\n"); + return 0; +}