1 1.1 mrg /* teta -- test file for the Dedekind eta function. 2 1.1 mrg 3 1.1 mrg Copyright (C) 2022 INRIA 4 1.1 mrg 5 1.1 mrg This file is part of GNU MPC. 6 1.1 mrg 7 1.1 mrg GNU MPC is free software; you can redistribute it and/or modify it under 8 1.1 mrg the terms of the GNU Lesser General Public License as published by the 9 1.1 mrg Free Software Foundation; either version 3 of the License, or (at your 10 1.1 mrg option) any later version. 11 1.1 mrg 12 1.1 mrg GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY 13 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 1.1 mrg FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 15 1.1 mrg more details. 16 1.1 mrg 17 1.1 mrg You should have received a copy of the GNU Lesser General Public License 18 1.1 mrg along with this program. If not, see http://www.gnu.org/licenses/ . 19 1.1 mrg */ 20 1.1 mrg 21 1.1 mrg #include <math.h> 22 1.1 mrg #include "mpc-tests.h" 23 1.1 mrg 24 1.1 mrg static void 25 1.1 mrg mpcb_j_err (mpcb_ptr j, mpc_srcptr z, unsigned long int err_re, 26 1.1 mrg unsigned long int err_im) 27 1.1 mrg /* Compute the j-function in z; err_re and err_im have the same meaning 28 1.1 mrg as in mpcb_eta_err. */ 29 1.1 mrg { 30 1.1 mrg const mpfr_prec_t p = mpc_get_prec (z); 31 1.1 mrg mpc_t z2; 32 1.1 mrg mpcb_t eta, eta2, sixteen; 33 1.1 mrg 34 1.1 mrg mpc_init2 (z2, p); 35 1.1 mrg mpcb_init (eta); 36 1.1 mrg mpcb_init (eta2); 37 1.1 mrg mpcb_init (sixteen); 38 1.1 mrg 39 1.1 mrg /* Compute f1 (z) = eta (z/2) / eta (z). */ 40 1.1 mrg mpcb_eta_err (eta, z, err_re, err_im); 41 1.1 mrg mpc_div_2ui (z2, z, 1, MPC_RNDNN); 42 1.1 mrg mpcb_eta_err (eta2, z2, err_re, err_im); 43 1.1 mrg mpcb_div (eta, eta2, eta); 44 1.1 mrg 45 1.1 mrg /* Compute gamma2 = (f1^24 + 16) / f1^8. */ 46 1.1 mrg mpcb_set_ui_ui (sixteen, 16, 0, p); 47 1.1 mrg mpcb_pow_ui (eta, eta, 8); 48 1.1 mrg mpcb_pow_ui (eta2, eta, 3); 49 1.1 mrg mpcb_add (eta2, eta2, sixteen); 50 1.1 mrg mpcb_div (eta2, eta2, eta); 51 1.1 mrg 52 1.1 mrg /* Compute j = gamma2^3. */ 53 1.1 mrg mpcb_pow_ui (j, eta2, 3); 54 1.1 mrg 55 1.1 mrg mpc_clear (z2); 56 1.1 mrg mpcb_clear (eta); 57 1.1 mrg mpcb_clear (eta2); 58 1.1 mrg mpcb_clear (sixteen); 59 1.1 mrg } 60 1.1 mrg 61 1.1 mrg 62 1.1 mrg static int 63 1.1 mrg test_eta (void) 64 1.1 mrg { 65 1.1 mrg const mpfr_prec_t p = 300; 66 1.1 mrg mpc_t z, eta; 67 1.1 mrg mpcb_t j; 68 1.1 mrg mpfr_t fuzz; 69 1.1 mrg mpz_t re_z, tmp; 70 1.1 mrg long int re, im; 71 1.1 mrg int ok; 72 1.1 mrg 73 1.1 mrg mpc_init2 (z, p); 74 1.1 mrg mpc_init2 (eta, p); 75 1.1 mrg mpcb_init (j); 76 1.1 mrg mpfr_init2 (fuzz, 2*p); 77 1.1 mrg 78 1.1 mrg mpfr_set_si (mpc_realref (z), -1, MPFR_RNDN); 79 1.1 mrg mpfr_set_ui (mpc_imagref (z), 163, MPFR_RNDD); 80 1.1 mrg mpfr_sqrt (mpc_imagref (z), mpc_imagref (z), MPFR_RNDD); 81 1.1 mrg mpc_div_2ui (z, z, 1, MPC_RNDNN); 82 1.1 mrg 83 1.1 mrg /* Check whether mpc_eta_fund avoids an infinite loop. */ 84 1.1 mrg mpc_eta_fund (eta, z, MPC_RNDNN); 85 1.1 mrg 86 1.1 mrg /* The error is bounded by 1/2 ulp in the real and 3 ulp in the 87 1.1 mrg imaginary part, see algorithms.tex. */ 88 1.1 mrg mpcb_j_err (j, z, 1, 6); 89 1.1 mrg 90 1.1 mrg /* Check whether j ((-1+sqrt(-163))/2) equals -262537412640768000. 91 1.1 mrg Rounding is impossible since the result is exact, and the imaginary 92 1.1 mrg part is 0; for a quick and dirty check, add the non-representable 93 1.1 mrg number 0.1 + 1.1 I and use the precisions that just work. */ 94 1.1 mrg mpfr_set_ui (fuzz, 1, MPFR_RNDN); 95 1.1 mrg mpfr_div_ui (fuzz, fuzz, 10, MPFR_RNDN); 96 1.1 mrg mpfr_add (mpc_realref (j->c), mpc_realref (j->c), fuzz, MPFR_RNDN); 97 1.1 mrg mpfr_add (mpc_imagref (j->c), mpc_imagref (j->c), fuzz, MPFR_RNDN); 98 1.1 mrg mpfr_add_ui (mpc_imagref (j->c), mpc_imagref (j->c), 1, MPFR_RNDN); 99 1.1 mrg ok = mpcb_can_round (j, 291, 234, MPC_RNDNN); 100 1.1 mrg mpcb_round (z, j, MPC_RNDNN); 101 1.1 mrg mpz_init (re_z); 102 1.1 mrg mpz_init_set_str (tmp, "-262537412640768000", 10); 103 1.1 mrg mpfr_get_z (re_z, mpc_realref (z), MPFR_RNDN); 104 1.1 mrg im = mpfr_get_si (mpc_imagref (z), MPFR_RNDN); 105 1.1 mrg ok &= (!mpz_cmp (re_z, tmp) && im == 1); 106 1.1 mrg if (!ok) { 107 1.1 mrg printf ("Error for -163:\n"); 108 1.1 mrg MPC_OUT (z); 109 1.1 mrg mpz_out_str (stdout, 10, re_z); 110 1.1 mrg printf ("\n"); 111 1.1 mrg } 112 1.1 mrg mpz_clear (tmp); 113 1.1 mrg mpz_clear (re_z); 114 1.1 mrg 115 1.1 mrg /* Check whether mpc_eta_fund (I) avoids an infinite loop. */ 116 1.1 mrg mpc_set_ui_ui (z, 0, 1, MPC_RNDNN); 117 1.1 mrg mpc_eta_fund (eta, z, MPC_RNDNN); 118 1.1 mrg 119 1.1 mrg /* Check whether j (I) equals 1728. */ 120 1.1 mrg mpcb_j_err (j, z, 0, 0); 121 1.1 mrg mpfr_add (mpc_realref (j->c), mpc_realref (j->c), fuzz, MPFR_RNDN); 122 1.1 mrg mpfr_add (mpc_imagref (j->c), mpc_imagref (j->c), fuzz, MPFR_RNDN); 123 1.1 mrg mpfr_add_ui (mpc_imagref (j->c), mpc_imagref (j->c), 1, MPFR_RNDN); 124 1.1 mrg ok &= mpcb_can_round (j, 292, 282, MPC_RNDNN); 125 1.1 mrg mpcb_round (z, j, MPC_RNDNN); 126 1.1 mrg re = mpfr_get_si (mpc_realref (z), MPFR_RNDN); 127 1.1 mrg im = mpfr_get_si (mpc_imagref (z), MPFR_RNDN); 128 1.1 mrg ok &= (re == 1728 && im == 1); 129 1.1 mrg if (!ok) { 130 1.1 mrg printf ("Error for -4:\n"); 131 1.1 mrg MPC_OUT (z); 132 1.1 mrg printf ("%li\n", re); 133 1.1 mrg } 134 1.1 mrg 135 1.1 mrg mpc_clear (eta); 136 1.1 mrg mpc_clear (z); 137 1.1 mrg mpcb_clear (j); 138 1.1 mrg mpfr_clear (fuzz); 139 1.1 mrg 140 1.1 mrg return !ok; 141 1.1 mrg } 142 1.1 mrg 143 1.1 mrg 144 1.1 mrg int 145 1.1 mrg main (void) 146 1.1 mrg { 147 1.1 mrg return test_eta (); 148 1.1 mrg } 149 1.1 mrg 150