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
83
84
85
/*
* SPDX-License-Identifier: MIT
* Copyright (c) 2023 - 2026. The DeepCausality Authors and Contributors. All Rights Reserved.
*/
use crate::;
use ;
/// A scalar carrying a **conjugation** and a real **modulus**, spanning the three scalar families
/// numerical linear algebra cares about: real fields, dual numbers (forward-mode AD), and complex.
///
/// `deep_causality_num` splits its scalar tower along orderability: [`Real`](crate::Real) /
/// [`Scalar`] cover ordered analytic scalars (`f32`/`f64`/`Float106`, and [`Dual`] for AD), while
/// complex numbers are unordered and live under [`Normed`](crate::Normed) / [`ComplexField`]. Those
/// worlds are incomparable, so no single stock bound covers them. `ConjugateScalar` is the bridge: it
/// names exactly the capabilities a Hermitian SVD / QR / inner-product / norm kernel needs —
/// conjugation (the identity for reals), a real squared modulus, the real part, and injection of a
/// real — so one generic implementation serves all three. The kernels reduce to their plain real
/// arithmetic when `conjugate` is the identity and `modulus_squared` is `x²`.
///
/// # Why not a supertrait of [`NormedScalar`](crate::NormedScalar)
/// [`NormedScalar`] (= [`Field`](crate::Field) + [`Normed`](crate::Normed)) is the cleaner
/// composition but its real type is a [`RealField`](crate::RealField). `ConjugateScalar` instead ties
/// its associated [`Real`](Self::Real) to the weaker [`Scalar`], because `Dual` is **not** a field or
/// `Normed` and its magnitude must remain a `Dual` for derivatives to flow through singular values.
/// For real and complex scalars the two notions agree; only `Dual` forces the weaker bound.
///
/// # Coherence
/// Implemented over the disjoint type constructors `T: RealField` (the real fields), `Dual<T>`, and
/// `Complex<T>`. A blanket `impl<T: Scalar>` would collide with the `Complex<T>` impl, but the
/// `RealField` blanket does not — `num` owns `RealField`, `Dual`, and `Complex` and can prove none of
/// the latter two is a `RealField` (the same reasoning [`Normed`](crate::Normed) relies on).
/// Real fields: conjugation is the identity, the modulus is `x²`, the real type is `Self`. The
/// `RealField` blanket covers `f32`/`f64`/`Float106` in one impl.