An fmpcb_t represents a complex number with error bounds. An fmpcb_t consists of a pair of real number balls of type fmprb_struct, representing the real and imaginary part with separate error bounds.
An fmpcb_t thus represents a rectangle \([m_1-r_1, m_1+r_1] + [m_2-r_2, m_2+r_2] i\) in the complex plane. This is used instead of a disk or square representation (consisting of a complex floating-point midpoint with a single radius), since it allows implementing many operations more conveniently by splitting into ball operations on the real and imaginary parts. It also allows tracking when complex numbers have an exact (for example exactly zero) real part and an inexact imaginary part, or vice versa.
The interface for the fmpcb_t type is slightly less developed than that for the fmprb_t type. In many cases, the user can easily perform missing operations by directly manipulating the real and imaginary parts.
An fmpcb_struct consists of a pair of fmprb_struct:s. An fmpcb_t is defined as an array of length one of type fmpcb_struct, permitting an fmpcb_t to be passed by reference.
Alias for fmpcb_struct *, used for vectors of numbers.
Alias for const fmpcb_struct *, used for vectors of numbers when passed as constant input to functions.
Macro returning a pointer to the real part of x as an fmprb_t.
Macro returning a pointer to the imaginary part of x as an fmprb_t.
Returns nonzero iff x and y are identical as sets, i.e. if the real and imaginary parts are equal as balls.
Note that this is not the same thing as testing whether both x and y certainly represent the same complex number, unless either x or y is exact (and neither contains NaN). To test whether both operands might represent the same mathematical quantity, use fmpcb_overlaps() or fmpcb_contains(), depending on the circumstance.
Returns nonzero iff x and y have some point in common.
Sets u to an upper bound for the absolute value of z, computed using a working precision of prec bits.
Sets u to a lower bound for the absolute value of z, computed using a working precision of prec bits.
Sets u to an upper bound for the error radius of z (the value is currently not computed tightly).
Returns the maximum of fmprb_bits applied to the real and imaginary parts of x, i.e. the minimum precision sufficient to represent x exactly.
Sets y to a a copy of x with both the real and imaginary parts trimmed (see fmprb_trim()).
Sets r to a real interval containing the complex argument (phase) of z. We define the complex argument have a discontinuity on \((-\infty,0]\), with the special value \(\operatorname{arg}(0) = 0\), and \(\operatorname{arg}(a+0i) = \pi\) for \(a < 0\). Equivalently, if \(z = a+bi\), the argument is given by \(\operatorname{atan2}(b,a)\) (see fmprb_atan2()).
Sets z to the sum of x and y.
Sets z to the difference of x and y.
Sets z to the product of x and y.
Sets z to the product of x and y. If at least one part of x or y is zero, the operations is reduced to two real multiplications. If x and y are the same pointers, they are assumed to represent the same mathematical quantity and the squaring formula is used.
Sets z to the product of x and y. If at least one part of x or y is zero, the operations is reduced to two real multiplications. Otherwise, letting \(x = a + bi\), \(y = c + di\), \(z = e + fi\), we use the formula \(e = ac - bd\), \(f = (a+b)(c+d) - ac - bd\), which requires three real multiplications instead of four.
The drawback of this algorithm is that the numerical stability is much worse than for the default algorithm. In particular, if one operand has a large error and the other a small error, the output error will be about twice that of the large input error, rather than about the same.
Sets z to x multiplied by \(2^e\), without rounding.
Sets z to z plus the product of x and y.
Sets y to the principal branch of the natural logarithm of z, computed as \(\log(a+bi) = \frac{1}{2} \log(a^2 + b^2) + i \operatorname{arg}(a+bi)\).
Sets y to the exponential function of z, computed as \(\exp(a+bi) = \exp(a) \left( \cos(b) + \sin(b) i \right)\).
Sets \(s = \sin z\), \(c = \cos z\), evaluated as \(\sin(a+bi) = \sin(a)\cosh(b) + i \cos(a)\sinh(b)\), \(\cos(a+bi) = \cos(a)\cosh(b) - i \sin(a)\sinh(b)\).
Sets \(s = \tan z = (\sin z) / (\cos z)\), evaluated as \(\tan(a+bi) = \sin(2a)/(\cos(2a) + \cosh(2b)) + i\sinh(2b)/(\cos(2a) + \cosh(2b))\). If \(|b|\) is small, the formula is evaluated as written; otherwise, we rewrite the hyperbolic functions in terms of decaying exponentials and evaluate the expression accurately using fmprb_expm1().
Sets \(s = \cot z = (\cos z) / (\sin z)\), evaluated as \(\cot(a+bi) = -\sin(2a)/(\cos(2a) - \cosh(2b)) + i\sinh(2b)/(\cos(2a) - \cosh(2b))\) using the same strategy as fmpcb_tan(). If \(|z|\) is close to zero, however, we evaluate \(1 / \tan(z)\) to avoid catastrophic cancellation.
Sets \(s = \sin \pi z\), \(c = \cos \pi z\), evaluating the trigonometric factors of the real and imaginary part accurately via fmprb_sin_cos_pi().
Sets \(s = \tan \pi z\). Uses the same algorithm as fmpcb_tan(), but evaluating the sine and cosine accurately via fmprb_sin_cos_pi().
Sets \(s = \cot \pi z\). Uses the same algorithm as fmpcb_cot(), but evaluating the sine and cosine accurately via fmprb_sin_cos_pi().
Sets \(y = b^e\) using binary exponentiation (with an initial division if \(e < 0\)). Provided that b and e are small enough and the exponent is positive, the exact power can be computed by setting the precision to FMPR_PREC_EXACT.
Note that these functions can get slow if the exponent is extremely large (in such cases fmpcb_pow() may be superior).
Sets \(z = x^y\), computed using binary exponentiation if \(y\) if a small exact integer, as \(z = (x^{1/2})^{2y}\) if \(y\) is a small exact half-integer, and generally as \(z = \exp(y \log x)\).
Sets r to the square root of z. If either the real or imaginary part is exactly zero, only a single real square root is needed. Generally, we use the formula \(\sqrt{a+bi} = u/2 + ib/u, u = \sqrt{2(|a+bi|+a)}\), requiring two real square root extractions.
Sets r to the reciprocal square root of z. If either the real or imaginary part is exactly zero, only a single real reciprocal square root is needed. Generally, we use the formula \(1/\sqrt{a+bi} = ((a+r) - bi)/v, r = |a+bi|, v = \sqrt{r |a+bi+r|^2}\), requiring one real square root and one real reciprocal square root.
Given one inverse m-th root r0 (with a valid error bound) of the complex number a, lift it from precision startprec to prec using Newton iteration, solving \(f(z) = (1/z)^m - a = 0\).
We require that a is exact and that the root is isolated from the origin. We also assume that the initial estimate is well isolated from the conjugate roots (so as to avoid converging to the wrong root). Given an error bound \(e_n\) for an input term \(z_n\) at step \(n\) of the Newton iteration, the error of the next term is bounded by \(e_{n+1} < |1/f'(z)| \sum_{k=2}^{\infty} (|f^{(k)}| / k!) e_n^k\). Replacing \(k!\) by \((k-2)!\) gives \(e_{n+1} < e_n^2 (m+1) (|z_n| / (|z_n| - e_n))^{-m-2} / |z_n|\).
Sets \(r = \exp((1/m) (\log(a) + 2 \pi i k))\). As \(k\), which is given by index, goes from \(0\) to \(m-1\), this expression gives all the m-th roots of the complex number a, starting with the principal m-th root (\(k = 0\)). We allow m to be negative.
The root_exp version evaluates the exponential directly.
The root_newton version uses Newton iteration, starting from an initial value generated by root_exp. It currently requires that a is exact and requires that m is not equal to LONG_MIN.
The root version makes a choice between the algorithms, selecting root_newton at high precision.
Sets y to the rising factorial \(x (x+1) (x+2) \cdots (x+n-1)\).
Sets \(y = \Gamma(x)\), the gamma function.
Sets \(y = 1/\Gamma(x)\), avoiding division by zero at the poles of the gamma function.
Sets \(y = \log \Gamma(x)\).
The branch cut of the logarithmic gamma function is placed on the negative half-axis, which means that \(\log \Gamma(z) + \log z = \log \Gamma(z+1)\) holds for all \(z\), whereas \(\log \Gamma(z) \ne \log(\Gamma(z))\) in general. Warning: this function does not currently use the reflection formula, and gets very slow for \(z\) far into the left half-plane.
Sets \(y = \psi(x) = (\log \Gamma(x))' = \Gamma'(x) / \Gamma(x)\).
Sets z to the value of the Riemann zeta function \(\zeta(s)\). Note: for computing derivatives with respect to \(s\), use fmpcb_poly_zeta_series() or the functions in the zeta module.