/* Copyright (C) 2013 Tom Bachmann 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 #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_naive(h, k) == dedekind_sum(h, k)); } 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; }