1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//! Double-double and quad-double floating-point arithmetic, scalar and on 8-lane SIMD vectors.
//!
//! A double-double is an unevaluated sum `hi + lo` of two `f64` (about 32 significant digits); a quad-double is a sum
//! of four (about 64 digits). The lane types run the same algorithms on 8 values at once, with **bitwise the same
//! results per lane** as the scalar types, on every backend:
//!
//! * [`v8::V8`]: 8 `f64` in one AVX-512 register, two AVX2 registers, four SSE2 or four NEON registers, or a plain
//! array (the cargo feature `portable` forces it), with fused multiply-add throughout.
//! * [`simd`]: the backends behind `V8`. [`simd::dispatch`] runs code written once over the backend on the best one
//! the CPU has, detected at run time; [`native`] has the lane types on the backend the build's target features
//! select at compile time.
//! * [`dd::DD`] scalar and [`dv::DV`] 8-lane double-double; [`dv::DotAcc`] a sum-of-products accumulator.
//! * [`qd::QD`] scalar and [`qv::QV`] 8-lane quad-double (the algorithms of Hida, Li and Bailey's QD library, with two
//! repairs found by this crate's tests), exact decimal parsing and printing;
//! [`qd::QdAcc`] and [`qv::QDotAcc`] accumulators.
//! * [`exact`]: exact dyadic and decimal arithmetic, the reference the tests compare against.
//! * [`dual`]: forward-mode dual numbers over these lanes ([`dual::Du`] double-double value and tangent,
//! [`dual::Dtn`] a double-double value with N f64 tangents, and f64 variants), behind the [`dual::Lane`] trait, so
//! one generic code gives values and exact derivatives; [`dual::Counted`] counts the operations of such code.
//! * [`field`]: 8 B values of a lane type as B lane vectors ([`field::Fl`]), with Cauchy products, Horner evaluation
//! a constant double-double matrix applied to them ([`field::DMat`]) and solves with a `DDLu`, refined in the lane
//! type ([`field::FieldSolve`]): the arithmetic of power-series methods.
//! * [`linalg`]: dense LU with partial pivoting in double-double (and blocked in f64 for mixed precision), solves,
//! transpose solves, solves refined to quad-double and Gram matrices; [`linalg::lu_rect_f64`], the f64 LU of the
//! first columns of a rectangular block (the step of a block LU), and [`linalg::StaircaseLu`], the LU of a staircase
//! system with one global parameter (the Newton system of multiple shooting) built from those steps.
//!
//! All operations are IEEE round-to-nearest with no reassociation, which the error-free transformations need.
//!
//! The cargo feature `f128` adds conversions between `f128` and [`dd::DD`] and [`qd::QD`]. It needs a nightly
//! compiler, as `f128` is unstable.
//!
//! ```
//! use multidouble::dd::DD;
//! use multidouble::qd::QD;
//!
//! let third = DD::from_f64(1.0) / DD::from_f64(3.0);
//! assert!(((third * DD::from_f64(3.0)) - DD::from_f64(1.0)).to_f64().abs() < 1e-31);
//!
//! let x: QD = "1.41421356237309504880168872420969807856967187537694807317667973799".parse().unwrap();
//! assert!((x * x - QD::from_f64(2.0)).to_f64().abs() < 1e-62);
//! ```
// Numerical kernels index several arrays with one loop variable, and the lane and accumulator types keep inherent
// add/sub/mul/div methods (the std::ops traits are implemented where they apply).
/// The lane types on the compile-time backend [`simd::Native`], for code that does not dispatch.
/// The README's examples, compiled and run as doctests.
;