/*
 * funcs.h: list of functions which return Spigot objects describing
 * mathematical constants, operators and functions.
 */

#include <vector>

/* In consts.cpp: */
Spigot *spigot_pi();
Spigot *spigot_tau();
Spigot *spigot_e();
Spigot *spigot_phi();
Spigot *spigot_apery();

/* In rational.cpp: */
Spigot *spigot_integer(bigint const &n);
Spigot *spigot_rational(bigint const &n, bigint const &d);

/* In io.cpp: */
Spigot *spigot_basefile(int base, const char *filename, bool exact);
Spigot *spigot_cfracfile(const char *filename, bool exact);
#ifdef HAVE_FDS
Spigot *spigot_basefd(int base, int fd);
Spigot *spigot_cfracfd(int fd);
#endif

/* In gosper.cpp: */
Spigot *spigot_add(Spigot *a, Spigot *b);
Spigot *spigot_sub(Spigot *a, Spigot *b);
Spigot *spigot_mul(Spigot *a, Spigot *b);
Spigot *spigot_square(Spigot *a);
Spigot *spigot_invsquare(Spigot *a);
Spigot *spigot_quadratic(Spigot *a, int a2, int a1, int a0);
Spigot *spigot_div(Spigot *a, Spigot *b);
Spigot *spigot_combine(Spigot *a, Spigot *b,
                       int nxy, int nx, int ny, int nc,
                       int dxy, int dx, int dy, int dc);

/* In sqrt.cpp: */
Spigot *spigot_sqrt(Spigot *a);
Spigot *spigot_hypot(Spigot *a, Spigot *b);
Spigot *spigot_cbrt(Spigot *a);

/* In unary.cpp: */
Spigot *spigot_reciprocal(Spigot *a);
Spigot *spigot_neg(Spigot *a);
Spigot *spigot_abs(Spigot *a);
Spigot *spigot_mod(Spigot *a, Spigot *b);
Spigot *spigot_rem(Spigot *a, Spigot *b);
Spigot *spigot_rational_mul(Spigot *a, const bigint &n, const bigint &d);
Spigot *spigot_mobius(Spigot *x,
                      const bigint &a, const bigint &b,
                      const bigint &c, const bigint &d);
Spigot *spigot_frac(Spigot *a);
Spigot *spigot_floor(Spigot *a);
Spigot *spigot_ceil(Spigot *a);

/* In trig.cpp: */
Spigot *spigot_sin(Spigot *a);
Spigot *spigot_cos(Spigot *a);
Spigot *spigot_tan(Spigot *a);
Spigot *spigot_asin(Spigot *a);
Spigot *spigot_acos(Spigot *a);
Spigot *spigot_atan(Spigot *a);
Spigot *spigot_atan2(Spigot *a, Spigot *b);
Spigot *spigot_sind(Spigot *a);
Spigot *spigot_cosd(Spigot *a);
Spigot *spigot_tand(Spigot *a);
Spigot *spigot_asind(Spigot *a);
Spigot *spigot_acosd(Spigot *a);
Spigot *spigot_atand(Spigot *a);
Spigot *spigot_atan2d(Spigot *a, Spigot *b);

/* In exp.cpp: */
Spigot *spigot_exp(Spigot *a);
Spigot *spigot_log(Spigot *a);
Spigot *spigot_exp2(Spigot *a);
Spigot *spigot_exp10(Spigot *a);
Spigot *spigot_log_to_base(Spigot *input, Spigot *base);
Spigot *spigot_log_wrapper(const std::vector<Spigot *> &args);
Spigot *spigot_log2(Spigot *a);
Spigot *spigot_log10(Spigot *a);
Spigot *spigot_pow(Spigot *a, Spigot *b);
Spigot *spigot_expm1(Spigot *a);
Spigot *spigot_log1p(Spigot *a);
Spigot *spigot_sinh(Spigot *a);
Spigot *spigot_cosh(Spigot *a);
Spigot *spigot_tanh(Spigot *a);
Spigot *spigot_asinh(Spigot *a);
Spigot *spigot_acosh(Spigot *a);
Spigot *spigot_atanh(Spigot *a);

/* In gamma.cpp: */
Spigot *spigot_lgamma(Spigot *a);
Spigot *spigot_gamma(Spigot *a);

/* In erf.cpp: */
Spigot *spigot_erf(Spigot *a);
Spigot *spigot_erfc(Spigot *a);
Spigot *spigot_Phi(Spigot *a);
Spigot *spigot_erfinv(Spigot *a);
Spigot *spigot_erfcinv(Spigot *a);
Spigot *spigot_Phiinv(Spigot *a);

/* In lambertw.cpp: */
Spigot *spigot_lambertw_pos(Spigot *x);
Spigot *spigot_lambertw_neg(Spigot *x);

/* In algebraic.cpp: */
Spigot *spigot_algebraic(const std::vector<bigint> &aP,
                         bigint nlo, bigint nhi, bigint d);
Spigot *spigot_algebraic_wrapper(const std::vector<Spigot *> &args);

/* In expint.cpp: */
Spigot *spigot_eulergamma();
Spigot *spigot_En(Spigot *n, Spigot *x);
Spigot *spigot_Ei(Spigot *x);
Spigot *spigot_Ein(Spigot *x);
Spigot *spigot_E1(Spigot *x);
Spigot *spigot_li(Spigot *x);
Spigot *spigot_Li(Spigot *x);

/* In trigint.cpp: */
Spigot *spigot_Si(Spigot *x);
Spigot *spigot_si(Spigot *x);
Spigot *spigot_Cin(Spigot *x);
Spigot *spigot_Ci(Spigot *x);
Spigot *spigot_UFresnelS(Spigot *x);
Spigot *spigot_UFresnelC(Spigot *x);
Spigot *spigot_FresnelS(Spigot *x);
Spigot *spigot_FresnelC(Spigot *x);

/* In zeta.cpp: */
Spigot *spigot_zeta(Spigot *x);

/* In monotone.cpp (a utility class used by other function implementations,
 * not suitable for direct use by clients): */
struct MonotoneConstructor {
    virtual ~MonotoneConstructor() {}
    virtual MonotoneConstructor *clone() = 0;
    virtual Spigot *construct(const bigint &n, const bigint &d) = 0;
};
Spigot *spigot_monotone(MonotoneConstructor *f, Spigot *x);
Spigot *spigot_monotone_invert(MonotoneConstructor *f, bool increasing,
                               bigint n1, bigint n2, bigint d, Spigot *x);
