utility functions acb_real_abs, sgn, heaviside, floor, ceil, min, max

This commit is contained in:
fredrik 2018-02-10 22:31:33 +01:00
parent af96e2cf20
commit fbe994f446
12 changed files with 517 additions and 107 deletions

8
acb.h
View file

@ -404,6 +404,14 @@ void acb_sgn(acb_t res, const acb_t z, slong prec);
void acb_csgn(arb_t res, const acb_t z); void acb_csgn(arb_t res, const acb_t z);
void acb_real_abs(acb_t res, const acb_t z, int analytic, slong prec);
void acb_real_sgn(acb_t res, const acb_t z, int analytic, slong prec);
void acb_real_heaviside(acb_t res, const acb_t z, int analytic, slong prec);
void acb_real_floor(acb_t res, const acb_t z, int analytic, slong prec);
void acb_real_ceil(acb_t res, const acb_t z, int analytic, slong prec);
void acb_real_max(acb_t res, const acb_t x, const acb_t y, int analytic, slong prec);
void acb_real_min(acb_t res, const acb_t x, const acb_t y, int analytic, slong prec);
ACB_INLINE void ACB_INLINE void
acb_add(acb_t z, const acb_t x, const acb_t y, slong prec) acb_add(acb_t z, const acb_t x, const acb_t y, slong prec)
{ {

40
acb/real_abs.c Normal file
View file

@ -0,0 +1,40 @@
/*
Copyright (C) 2018 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.h"
void
acb_real_abs(acb_t res, const acb_t z, int analytic, slong prec)
{
if (!acb_is_finite(z) || (analytic && arb_contains_zero(acb_realref(z))))
{
acb_indeterminate(res);
}
else
{
if (arb_is_nonnegative(acb_realref(z)))
{
acb_set_round(res, z, prec);
}
else if (arb_is_negative(acb_realref(z)))
{
acb_neg_round(res, z, prec);
}
else
{
acb_t t;
acb_init(t);
acb_neg(t, res);
acb_union(res, z, t, prec);
acb_clear(t);
}
}
}

27
acb/real_ceil.c Normal file
View file

@ -0,0 +1,27 @@
/*
Copyright (C) 2018 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.h"
void
acb_real_ceil(acb_t res, const acb_t z, int analytic, slong prec)
{
if (!acb_is_finite(z) || (analytic && arb_contains_int(acb_realref(z))))
{
acb_indeterminate(res);
}
else
{
arb_ceil(acb_realref(res), acb_realref(z), prec);
arb_set_round(acb_imagref(res), acb_imagref(z), prec);
}
}

26
acb/real_floor.c Normal file
View file

@ -0,0 +1,26 @@
/*
Copyright (C) 2018 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.h"
void
acb_real_floor(acb_t res, const acb_t z, int analytic, slong prec)
{
if (!acb_is_finite(z) || (analytic && arb_contains_int(acb_realref(z))))
{
acb_indeterminate(res);
}
else
{
arb_floor(acb_realref(res), acb_realref(z), prec);
arb_set_round(acb_imagref(res), acb_imagref(z), prec);
}
}

25
acb/real_heaviside.c Normal file
View file

@ -0,0 +1,25 @@
/*
Copyright (C) 2018 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.h"
void
acb_real_heaviside(acb_t res, const acb_t z, int analytic, slong prec)
{
acb_real_sgn(res, z, analytic, prec);
if (acb_is_finite(res))
{
acb_add_ui(res, res, 1, prec);
acb_mul_2exp_si(res, res, -1);
}
}

39
acb/real_max.c Normal file
View file

@ -0,0 +1,39 @@
/*
Copyright (C) 2018 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.h"
void
acb_real_max(acb_t res, const acb_t x, const acb_t y, int analytic, slong prec)
{
arb_t t;
if (!acb_is_finite(x) || !acb_is_finite(y))
{
acb_indeterminate(res);
return;
}
arb_init(t);
arb_sub(t, acb_realref(x), acb_realref(y), prec);
if (arb_is_positive(t))
acb_set_round(res, x, prec);
else if (arb_is_negative(t))
acb_set_round(res, y, prec);
else if (!analytic)
acb_union(res, x, y, prec);
else
acb_indeterminate(res);
arb_clear(t);
}

39
acb/real_min.c Normal file
View file

@ -0,0 +1,39 @@
/*
Copyright (C) 2018 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.h"
void
acb_real_min(acb_t res, const acb_t x, const acb_t y, int analytic, slong prec)
{
arb_t t;
if (!acb_is_finite(x) || !acb_is_finite(y))
{
acb_indeterminate(res);
return;
}
arb_init(t);
arb_sub(t, acb_realref(x), acb_realref(y), prec);
if (arb_is_positive(t))
acb_set_round(res, y, prec);
else if (arb_is_negative(t))
acb_set_round(res, x, prec);
else if (!analytic)
acb_union(res, x, y, prec);
else
acb_indeterminate(res);
arb_clear(t);
}

27
acb/real_sgn.c Normal file
View file

@ -0,0 +1,27 @@
/*
Copyright (C) 2018 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.h"
void
acb_real_sgn(acb_t res, const acb_t z, int analytic, slong prec)
{
if (!acb_is_finite(z) || (analytic && arb_contains_zero(acb_realref(z))))
{
acb_indeterminate(res);
}
else
{
acb_csgn(acb_realref(res), z);
arb_zero(acb_imagref(res));
}
}

View file

@ -11,36 +11,6 @@
#include "acb_calc.h" #include "acb_calc.h"
/* Absolute value function on R extended to a holomorphic function in the left
and right half planes. */
void
acb_holomorphic_abs(acb_ptr res, const acb_t z, int holomorphic, slong prec)
{
if (!acb_is_finite(z) || (holomorphic && arb_contains_zero(acb_realref(z))))
{
acb_indeterminate(res);
}
else
{
if (arb_is_nonnegative(acb_realref(z)))
{
acb_set_round(res, z, prec);
}
else if (arb_is_negative(acb_realref(z)))
{
acb_neg_round(res, z, prec);
}
else
{
acb_t t;
acb_init(t);
acb_neg(t, res);
acb_union(res, z, t, prec);
acb_clear(t);
}
}
}
/* Square root function on C with detection of the branch cut. */ /* Square root function on C with detection of the branch cut. */
void void
acb_holomorphic_sqrt(acb_ptr res, const acb_t z, int holomorphic, slong prec) acb_holomorphic_sqrt(acb_ptr res, const acb_t z, int holomorphic, slong prec)
@ -150,7 +120,7 @@ f_helfgott(acb_ptr res, const acb_t z, void * param, slong order, slong prec)
acb_mul(res, res, z, prec); acb_mul(res, res, z, prec);
acb_add_si(res, res, -6, prec); acb_add_si(res, res, -6, prec);
acb_holomorphic_abs(res, res, order != 0, prec); acb_real_abs(res, res, order != 0, prec);
if (acb_is_finite(res)) if (acb_is_finite(res))
{ {
@ -226,6 +196,120 @@ f_wolfram(acb_ptr res, const acb_t z, void * param, slong order, slong prec)
return 0; return 0;
} }
/* more tests for the individual acb_real_* functions */
/* abs(sin(x))*cos(1+x) */
int
f_abs(acb_ptr res, const acb_t z, void * param, slong order, slong prec)
{
acb_t s, c;
acb_init(s);
acb_init(c);
acb_sin(s, z, prec);
acb_add_ui(c, z, 1, prec);
acb_cos(c, c, prec);
acb_real_abs(s, s, order != 0, prec);
acb_mul(res, s, c, prec);
acb_clear(s);
acb_clear(c);
return 0;
}
/* sign(sin(x))*cos(1+x) */
int
f_sgn(acb_ptr res, const acb_t z, void * param, slong order, slong prec)
{
acb_t s, c;
acb_init(s);
acb_init(c);
acb_sin(s, z, prec);
acb_add_ui(c, z, 1, prec);
acb_cos(c, c, prec);
acb_real_sgn(s, s, order != 0, prec);
acb_mul(res, s, c, prec);
acb_clear(s);
acb_clear(c);
return 0;
}
/* heaviside(sin(x))*cos(1+x) */
int
f_heaviside(acb_ptr res, const acb_t z, void * param, slong order, slong prec)
{
acb_t s, c;
acb_init(s);
acb_init(c);
acb_sin(s, z, prec);
acb_add_ui(c, z, 1, prec);
acb_cos(c, c, prec);
acb_real_heaviside(s, s, order != 0, prec);
acb_mul(res, s, c, prec);
acb_clear(s);
acb_clear(c);
return 0;
}
/* floor(x-5) cos(1+x) */
int
f_floor(acb_ptr res, const acb_t z, void * param, slong order, slong prec)
{
acb_t c;
acb_init(c);
acb_add_ui(c, z, 1, prec);
acb_cos(c, c, prec);
acb_sub_ui(res, z, 5, prec);
acb_real_floor(res, res, order != 0, prec);
acb_mul(res, res, c, prec);
acb_clear(c);
return 0;
}
/* ceil(x-5) cos(1+x) */
int
f_ceil(acb_ptr res, const acb_t z, void * param, slong order, slong prec)
{
acb_t c;
acb_init(c);
acb_add_ui(c, z, 1, prec);
acb_cos(c, c, prec);
acb_sub_ui(res, z, 5, prec);
acb_real_ceil(res, res, order != 0, prec);
acb_mul(res, res, c, prec);
acb_clear(c);
return 0;
}
/* max(sin(x),cos(x)) */
int
f_max(acb_ptr res, const acb_t z, void * param, slong order, slong prec)
{
acb_t s, c;
acb_init(s);
acb_init(c);
acb_sin_cos(s, c, z, prec);
acb_real_max(res, s, c, order != 0, prec);
acb_clear(s);
acb_clear(c);
return 0;
}
/* min(sin(x),cos(x)) */
int
f_min(acb_ptr res, const acb_t z, void * param, slong order, slong prec)
{
acb_t s, c;
acb_init(s);
acb_init(c);
acb_sin_cos(s, c, z, prec);
acb_real_min(res, s, c, order != 0, prec);
acb_clear(s);
acb_clear(c);
return 0;
}
int main() int main()
{ {
slong iter; slong iter;
@ -386,6 +470,108 @@ int main()
mag_clear(tol); mag_clear(tol);
} }
/* more tests for the individual real extensions */
{
acb_t a, b, z, w;
slong prec;
mag_t tol;
acb_init(a);
acb_init(b);
acb_init(z);
acb_init(w);
mag_clear(tol);
acb_zero(a);
acb_set_ui(b, 10);
prec = 53;
mag_set_ui_2exp_si(tol, 1, -prec);
acb_calc_integrate(z, f_abs, NULL, a, b, prec, tol, NULL, prec);
arb_set_str(acb_realref(w), "-1.3517710956465318592 +/- 1e-17", prec);
if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 10)
{
flint_printf("FAIL (abs)\n");
flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n");
flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n");
flint_abort();
}
acb_calc_integrate(z, f_sgn, NULL, a, b, prec, tol, NULL, prec);
arb_set_str(acb_realref(w), "-4.8903066871045720895 +/- 1e-17", prec);
if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 10)
{
flint_printf("FAIL (sgn)\n");
flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n");
flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n");
flint_abort();
}
acb_calc_integrate(z, f_heaviside, NULL, a, b, prec, tol, NULL, prec);
arb_set_str(acb_realref(w), "-3.3658839392315860266 +/- 1e-17", prec);
if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 10)
{
flint_printf("FAIL (heaviside)\n");
flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n");
flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n");
flint_abort();
}
acb_calc_integrate(z, f_floor, NULL, a, b, prec, tol, NULL, prec);
arb_set_str(acb_realref(w), "-0.36232328857344524392 +/- 1e-17", prec);
if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 16)
{
flint_printf("FAIL (floor)\n");
flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n");
flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n");
flint_abort();
}
acb_calc_integrate(z, f_ceil, NULL, a, b, prec, tol, NULL, prec);
arb_set_str(acb_realref(w), "-2.2037844799320452076 +/- 1e-17", prec);
if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 16)
{
flint_printf("FAIL (ceil)\n");
flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n");
flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n");
flint_abort();
}
acb_calc_integrate(z, f_max, NULL, a, b, prec, tol, NULL, prec);
arb_set_str(acb_realref(w), "5.0817122161957375987 +/- 1e-17", prec);
if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 10)
{
flint_printf("FAIL (max)\n");
flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n");
flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n");
flint_abort();
}
acb_calc_integrate(z, f_min, NULL, a, b, prec, tol, NULL, prec);
arb_set_str(acb_realref(w), "-3.7866617980086549598 +/- 1e-17", prec);
if (!acb_overlaps(z, w) || acb_rel_accuracy_bits(z) < prec - 10)
{
flint_printf("FAIL (min)\n");
flint_printf("z = "); acb_printn(z, 20, 0); flint_printf("\n");
flint_printf("w = "); acb_printn(w, 20, 0); flint_printf("\n");
flint_abort();
}
acb_clear(a);
acb_clear(b);
acb_clear(z);
acb_clear(w);
mag_clear(tol);
}
flint_randclear(state); flint_randclear(state);
flint_cleanup(); flint_cleanup();
flint_printf("PASS\n"); flint_printf("PASS\n");

View file

@ -387,6 +387,8 @@ Arithmetic
.. function:: void acb_neg(acb_t z, const acb_t x) .. function:: void acb_neg(acb_t z, const acb_t x)
.. function:: void acb_neg_round(acb_t z, const acb_t x, slong prec)
Sets *z* to the negation of *x*. Sets *z* to the negation of *x*.
.. function:: void acb_conj(acb_t z, const acb_t x) .. function:: void acb_conj(acb_t z, const acb_t x)
@ -979,6 +981,63 @@ Other special functions
`a = U_n(x), b = U_{n-1}(x)`. `a = U_n(x), b = U_{n-1}(x)`.
Aliasing between *a*, *b* and *x* is not permitted. Aliasing between *a*, *b* and *x* is not permitted.
Piecewise real functions
-------------------------------------------------------------------------------
The following methods extend common piecewise real functions to piecewise
complex analytic functions, useful together with the
:ref:`acb_calc.h <acb-calc>` module.
If *analytic* is set, evaluation on a discontinuity or non-analytic point
gives a NaN result.
.. function:: void acb_real_abs(acb_t res, const acb_t z, int analytic, slong prec)
The absolute value is extended to `+z` in the right half plane and
`-z` in the left half plane, with a discontinuity on the vertical line
`\operatorname{Re}(z) = 0`.
.. function:: void acb_real_sgn(acb_t res, const acb_t z, int analytic, slong prec)
The sign function is extended to `+1` in the right half plane and
`-1` in the left half plane, with a discontinuity on the vertical line
`\operatorname{Re}(z) = 0`.
If *analytic* is not set, this is effectively the same function as
:func:`acb_csgn`.
.. function:: void acb_real_heaviside(acb_t res, const acb_t z, int analytic, slong prec)
The Heaviside step function (or unit step function) is extended to `+1` in
the right half plane and `0` in the left half plane, with a discontinuity on
the vertical line `\operatorname{Re}(z) = 0`.
.. function:: void acb_real_floor(acb_t res, const acb_t z, int analytic, slong prec)
The floor function is extended to a piecewise constant function
equal to `n` in the strips with real part `(n,n+1)`, with discontinuities
on the vertical lines `\operatorname{Re}(z) = n`.
.. function:: void acb_real_ceil(acb_t res, const acb_t z, int analytic, slong prec)
The ceiling function is extended to a piecewise constant function
equal to `n+1` in the strips with real part `(n,n+1)`, with discontinuities
on the vertical lines `\operatorname{Re}(z) = n`.
.. function:: void acb_real_max(acb_t res, const acb_t x, const acb_t y, int analytic, slong prec)
The real function `\max(x,y)` is extended to a piecewise analytic function
of two variables by returning `x` when
`\operatorname{Re}(x) \ge \operatorname{Re}(y)`
and returning `y` when `\operatorname{Re}(x) < \operatorname{Re}(y)`,
with discontinuities where `\operatorname{Re}(x) = \operatorname{Re}(y)`.
.. function:: void acb_real_min(acb_t res, const acb_t x, const acb_t y, int analytic, slong prec)
The real function `\min(x,y)` is extended to a piecewise analytic function
of two variables by returning `x` when
`\operatorname{Re}(x) \le \operatorname{Re}(y)`
and returning `y` when `\operatorname{Re}(x) > \operatorname{Re}(y)`,
with discontinuities where `\operatorname{Re}(x) = \operatorname{Re}(y)`.
Vector functions Vector functions
------------------------------------------------------------------------------- -------------------------------------------------------------------------------

View file

@ -51,26 +51,16 @@ Types, macros and constants
functions (sqrt, log, pow, etc.) that test holomorphicity of their functions (sqrt, log, pow, etc.) that test holomorphicity of their
arguments individually. arguments individually.
The built-in methods :func:`acb_real_abs`, :func:`acb_real_sgn`,
:func:`acb_real_heaviside`, :func:`acb_real_floor`, :func:`acb_real_ceil`,
:func:`acb_real_max`, :func:`acb_real_min` provide piecewise holomorphic
functions that are useful for integrating piecewise-defined real functions.
For example, here we define a piecewise holomorphic extension For example, here we define a piecewise holomorphic extension
of the function of the function
`f(z) = \sqrt{\lfloor z \rfloor}` (for simplicity, without implementing `f(z) = \sqrt{\lfloor z \rfloor}` (for simplicity, without implementing
derivatives):: derivatives)::
/* Floor function on R extended to a piecewise holomorphic function in
vertical strips. */
void holomorphic_floor(acb_t res, const acb_t z, int holomorphic, slong prec)
{
if (!acb_is_finite(z) || (holomorphic && arb_contains_int(acb_realref(z))))
{
acb_indeterminate(res);
}
else
{
arb_floor(acb_realref(res), acb_realref(z), prec);
arb_set_round(acb_imagref(res), acb_imagref(z), prec);
}
}
/* Square root function on C with detection of the branch cut. */ /* Square root function on C with detection of the branch cut. */
void holomorphic_sqrt(acb_t res, const acb_t z, int holomorphic, slong prec) void holomorphic_sqrt(acb_t res, const acb_t z, int holomorphic, slong prec)
{ {
@ -90,7 +80,7 @@ Types, macros and constants
{ {
if (order > 1) flint_abort(); /* derivatives not implemented */ if (order > 1) flint_abort(); /* derivatives not implemented */
holomorphic_floor(out, inp, order != 0, prec); acb_real_floor(out, inp, order != 0, prec);
holomorphic_sqrt(out, out, order != 0, prec); holomorphic_sqrt(out, out, order != 0, prec);
return 0; return 0;
} }

View file

@ -19,52 +19,6 @@
/* Useful helper functions */ /* Useful helper functions */
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* Absolute value function on R extended to a holomorphic function in the left
and right half planes. */
void
acb_holomorphic_abs(acb_ptr res, const acb_t z, int holomorphic, slong prec)
{
if (!acb_is_finite(z) || (holomorphic && arb_contains_zero(acb_realref(z))))
{
acb_indeterminate(res);
}
else
{
if (arb_is_nonnegative(acb_realref(z)))
{
acb_set_round(res, z, prec);
}
else if (arb_is_negative(acb_realref(z)))
{
acb_neg_round(res, z, prec);
}
else
{
acb_t t;
acb_init(t);
acb_neg(t, res);
acb_union(res, z, t, prec);
acb_clear(t);
}
}
}
/* Floor function on R extended to a piecewise holomorphic function in
vertical strips. */
void
acb_holomorphic_floor(acb_ptr res, const acb_t z, int holomorphic, slong prec)
{
if (!acb_is_finite(z) || (holomorphic && arb_contains_int(acb_realref(z))))
{
acb_indeterminate(res);
}
else
{
arb_floor(acb_realref(res), acb_realref(z), prec);
arb_set_round(acb_imagref(res), acb_imagref(z), prec);
}
}
/* Square root function on C with detection of the branch cut. */ /* Square root function on C with detection of the branch cut. */
void void
acb_holomorphic_sqrt(acb_ptr res, const acb_t z, int holomorphic, slong prec) acb_holomorphic_sqrt(acb_ptr res, const acb_t z, int holomorphic, slong prec)
@ -104,7 +58,7 @@ f_floor(acb_ptr res, const acb_t z, void * param, slong order, slong prec)
if (order > 1) if (order > 1)
flint_abort(); /* Would be needed for Taylor method. */ flint_abort(); /* Would be needed for Taylor method. */
acb_holomorphic_floor(res, z, order != 0, prec); acb_real_floor(res, z, order != 0, prec);
return 0; return 0;
} }
@ -172,7 +126,7 @@ f_helfgott(acb_ptr res, const acb_t z, void * param, slong order, slong prec)
acb_mul(res, res, z, prec); acb_mul(res, res, z, prec);
acb_add_si(res, res, -6, prec); acb_add_si(res, res, -6, prec);
acb_holomorphic_abs(res, res, order != 0, prec); acb_real_abs(res, res, order != 0, prec);
if (acb_is_finite(res)) if (acb_is_finite(res))
{ {
@ -333,7 +287,7 @@ f_monster(acb_ptr res, const acb_t z, void * param, slong order, slong prec)
acb_init(t); acb_init(t);
acb_exp(t, z, prec); acb_exp(t, z, prec);
acb_holomorphic_floor(res, t, order != 0, prec); acb_real_floor(res, t, order != 0, prec);
if (acb_is_finite(res)) if (acb_is_finite(res))
{ {
@ -553,17 +507,7 @@ f_max_sin_cos(acb_ptr res, const acb_t z, void * param, slong order, slong prec)
acb_init(c); acb_init(c);
acb_sin_cos(s, c, z, prec); acb_sin_cos(s, c, z, prec);
acb_real_max(res, s, c, order != 0, prec);
acb_sub(res, s, c, prec);
if (arb_is_positive(acb_realref(res)))
acb_set(res, s);
else if (arb_is_negative(acb_realref(res)))
acb_set(res, c);
else if (order == 0)
acb_union(res, s, c, prec);
else
acb_indeterminate(res);
acb_clear(s); acb_clear(s);
acb_clear(c); acb_clear(c);