mirror of
https://github.com/vale981/arb
synced 2025-03-06 01:41:39 -05:00
199 lines
7 KiB
C
199 lines
7 KiB
C
/*
|
|
Copyright (C) 2022 Fredrik Johansson
|
|
|
|
This file is part of Arb.
|
|
Arb 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "acb_dirichlet.h"
|
|
|
|
void
|
|
acb_dirichlet_lerch_phi_test(acb_t res, const acb_t z, const acb_t s, const acb_t a, int algorithm, slong prec)
|
|
{
|
|
switch (algorithm % 3)
|
|
{
|
|
case 0:
|
|
acb_dirichlet_lerch_phi_direct(res, z, s, a, prec);
|
|
if (!acb_is_finite(res))
|
|
acb_dirichlet_lerch_phi(res, z, s, a, prec);
|
|
break;
|
|
case 1:
|
|
acb_dirichlet_lerch_phi_integral(res, z, s, a, prec);
|
|
break;
|
|
default:
|
|
acb_dirichlet_lerch_phi(res, z, s, a, prec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
acb_set_dddd(acb_t z, double a, double ar, double b, double br)
|
|
{
|
|
arf_set_d(arb_midref(acb_realref(z)), a);
|
|
mag_set_d(arb_radref(acb_realref(z)), ar);
|
|
arf_set_d(arb_midref(acb_imagref(z)), b);
|
|
mag_set_d(arb_radref(acb_imagref(z)), br);
|
|
}
|
|
|
|
#define NUM_TESTS 15
|
|
|
|
/* z, s, a, phi(z, s, a) */
|
|
const double testdata[NUM_TESTS][8] = {
|
|
{ 1.0, 0.00390625, 1.5, 0.0, 2.25, 0.0, 1.3422063426254739626, 0.13465412214420029791 },
|
|
{ 1.0, 0.0, 1.5, 0.0, 2.25, 0.0, 1.4975136076666680360, 0.0 },
|
|
{ 1.0, -0.00390625, 1.5, 0.0, 2.25, 0.0, 1.3422063426254739626, -0.13465412214420029791 },
|
|
{ 2.0, 0.00390625, 1.5, 0.0, 2.25, 0.0, -0.16955701974487404975, 0.61946301461898363407 },
|
|
{ 2.0, 0.0, 1.5, 0.0, 2.25, 0.0, -0.17140382129993246416, -0.62044054732729604008 },
|
|
{ 2.0, -0.00390625, 1.5, 0.0, 2.25, 0.0, -0.16955701974487404975, -0.61946301461898363407 },
|
|
{ 0.6875, 0.0, 0.0, 0.0, -1.0, 2.0, 3.2, 0.0 },
|
|
{ 0.0, 8.0, 1.0, 0.0, 1.0, -1.0, -0.21201062033942531891, 0.15142847985530888328 },
|
|
{ 0.0, 8.0, 1.0, 1.0, 1.0, -1.0, -0.18714764709994647918, -0.031327583631588241802 },
|
|
{ 1.875, 2.625, -1.0, 0.0, 1.0, 0.0, -0.10448979591836734694, -0.078367346938775510204 },
|
|
{ -2.5, -1.0, -3.75, 0.0, -3.75, 7.5, 195.9465378716877103, 889.34175804326870925 },
|
|
{ 0.0, -1.5, 1.0, 0.5, -1.0, 6.0, -0.20452787205323008395, 0.14062505401787546806 },
|
|
{ -3.0, 3.0, 9.5, 0.0, 0.0, -5.5, 5.5775511785583065106e-7, -4.488380385476415194e-7 },
|
|
{ -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, -0.75, 0.0 },
|
|
{ -3.0, 0.0, -2.0, 0.0, -2.0, 0.0, 1.84375, 0.0 },
|
|
};
|
|
|
|
int main()
|
|
{
|
|
slong iter;
|
|
flint_rand_t state;
|
|
|
|
flint_printf("lerch_phi....");
|
|
fflush(stdout);
|
|
|
|
flint_randinit(state);
|
|
|
|
/* check test values */
|
|
for (iter = 0; iter < 5 * arb_test_multiplier(); iter++)
|
|
{
|
|
slong i;
|
|
acb_t z, s, a, p1, p2;
|
|
int alg;
|
|
|
|
acb_init(z);
|
|
acb_init(s);
|
|
acb_init(a);
|
|
acb_init(p1);
|
|
acb_init(p2);
|
|
|
|
for (i = 0; i < NUM_TESTS; i++)
|
|
{
|
|
alg = n_randlimb(state);
|
|
|
|
acb_set_dddd(z, testdata[i][0], 0.0, testdata[i][1], 0.0);
|
|
acb_set_dddd(s, testdata[i][2], 0.0, testdata[i][3], 0.0);
|
|
acb_set_dddd(a, testdata[i][4], 1e-14, testdata[i][5], 1e-14);
|
|
acb_set_dddd(p2, testdata[i][6], 1e-14, testdata[i][7], 1e-14);
|
|
|
|
acb_dirichlet_lerch_phi_test(p1, z, s, a, alg, 2 + n_randint(state, 100));
|
|
|
|
if (!acb_overlaps(p1, p2))
|
|
{
|
|
flint_printf("FAIL (test value)\n");
|
|
flint_printf("z = "); acb_printd(z, 15); flint_printf("\n\n");
|
|
flint_printf("s = "); acb_printd(s, 15); flint_printf("\n\n");
|
|
flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n");
|
|
flint_printf("p1 = "); acb_printd(p1, 15); flint_printf("\n\n");
|
|
flint_printf("p2 = "); acb_printd(p2, 15); flint_printf("\n\n");
|
|
flint_abort();
|
|
}
|
|
}
|
|
|
|
acb_clear(z);
|
|
acb_clear(s);
|
|
acb_clear(a);
|
|
acb_clear(p1);
|
|
acb_clear(p2);
|
|
}
|
|
|
|
for (iter = 0; iter < 500 * arb_test_multiplier(); iter++)
|
|
{
|
|
acb_t z, s, a, b, r1, r2, r3;
|
|
slong prec1, prec2;
|
|
int alg1, alg2, alg3;
|
|
|
|
/* flint_printf("iter %wd\n", iter); */
|
|
|
|
acb_init(z);
|
|
acb_init(s);
|
|
acb_init(a);
|
|
acb_init(b);
|
|
acb_init(r1);
|
|
acb_init(r2);
|
|
acb_init(r3);
|
|
|
|
prec1 = 2 + n_randint(state, 200);
|
|
prec2 = 2 + n_randint(state, 200);
|
|
alg1 = n_randlimb(state);
|
|
alg2 = n_randlimb(state);
|
|
alg3 = n_randlimb(state);
|
|
|
|
acb_randtest(z, state, 1 + n_randint(state, 500), 3);
|
|
acb_randtest(s, state, 1 + n_randint(state, 500), 3);
|
|
acb_randtest(a, state, 1 + n_randint(state, 500), 3);
|
|
acb_randtest(b, state, 1 + n_randint(state, 500), 10);
|
|
acb_randtest(r1, state, 1 + n_randint(state, 500), 10);
|
|
acb_randtest(r2, state, 1 + n_randint(state, 500), 10);
|
|
|
|
if (n_randint(state, 2))
|
|
acb_set_si(z, n_randint(state, 5) - 2);
|
|
if (n_randint(state, 2))
|
|
acb_set_si(a, n_randint(state, 5) - 2);
|
|
if (n_randint(state, 2))
|
|
acb_set_si(s, n_randint(state, 5) - 2);
|
|
|
|
acb_dirichlet_lerch_phi_test(r1, z, s, a, alg1, prec1);
|
|
acb_dirichlet_lerch_phi_test(r2, z, s, a, alg2, prec2);
|
|
|
|
if (!acb_overlaps(r1, r2))
|
|
{
|
|
flint_printf("FAIL: overlap\n\n");
|
|
flint_printf("iter = %wd\n\n", iter);
|
|
flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n");
|
|
flint_printf("s = "); acb_printd(s, 30); flint_printf("\n\n");
|
|
flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n");
|
|
flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n");
|
|
flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n");
|
|
flint_abort();
|
|
}
|
|
|
|
/* test phi(z,s,a) = z*phi(z,s,a+1) + a^-s */
|
|
acb_add_ui(b, a, 1, prec2);
|
|
acb_dirichlet_lerch_phi_test(r2, z, s, b, alg3, prec2);
|
|
acb_neg(r3, s);
|
|
acb_pow(r3, a, r3, prec2);
|
|
acb_addmul(r3, r2, z, prec2);
|
|
|
|
if (!acb_overlaps(r1, r3))
|
|
{
|
|
flint_printf("FAIL (2): overlap\n\n");
|
|
flint_printf("iter = %wd\n\n", iter);
|
|
flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n");
|
|
flint_printf("s = "); acb_printd(s, 30); flint_printf("\n\n");
|
|
flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n");
|
|
flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n");
|
|
flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n");
|
|
flint_printf("r3 = "); acb_printd(r3, 30); flint_printf("\n\n");
|
|
flint_abort();
|
|
}
|
|
|
|
acb_clear(z);
|
|
acb_clear(s);
|
|
acb_clear(a);
|
|
acb_clear(b);
|
|
acb_clear(r1);
|
|
acb_clear(r2);
|
|
acb_clear(r3);
|
|
}
|
|
|
|
flint_randclear(state);
|
|
flint_cleanup();
|
|
flint_printf("PASS\n");
|
|
return EXIT_SUCCESS;
|
|
}
|