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
86
87
88
89
90
91
92
93
94
95
//! Generic projection trait for automatic differentiation support.
//!
//! [`ProjectGeneric`] is the AD-aware counterpart to the object-safe
//! [`crate::operation::Operation`] trait. Unlike `Operation`, which is
//! intentionally kept object-safe and works on `f64` only, `ProjectGeneric`
//! is generic over any [`Scalar`], enabling projection
//! structs to be driven with dual numbers for exact Jacobian computation.
//!
//! # Design notes
//!
//! - **Not object-safe**: the generic method parameter makes this trait
//! incompatible with `dyn Trait`. This is intentional: it is an additive
//! path, not a replacement for `Operation`.
//! - **Zero run-time cost at `f64`**: when instantiated with `S = f64`, the
//! compiler monomorphises to exactly the same code as a plain `f64` impl.
//! - **Parity preserved**: existing `factors.rs` finite-difference code is
//! untouched. `factors_exact()` (Batch 2) will call `project_fwd_generic`
//! with `Dual1<2>` to compute the exact Jacobian.
use crate::;
/// Non-object-safe projection trait parameterised over a [`Scalar`] type.
///
/// Projection structs implement this trait (alongside [`crate::operation::Operation`])
/// to opt into the AD path. Implementing this trait for a struct makes it
/// possible to compute exact distortion factors by substituting `Dual1<2>`
/// for the scalar type.
///
/// # Type parameters
///
/// The implementor is generic over the *point* type rather than over `self`,
/// to keep `&self` immutable and avoid lifetime issues.
/// Object-safe wrapper: monomorphises [`ProjectGeneric`] for `Dual1<2>`.
///
/// Because `ProjectGeneric` is not object-safe (it has a generic method),
/// this trait provides a concrete, object-safe interface for the 2-D Jacobian
/// computation. A blanket implementation is provided for any `T` that
/// implements [`ProjectGeneric`].
///
/// Stored in `Pj` as `Arc<dyn ProjectGenericBox>` to avoid repeated monomorphisation.
/// Blanket implementation: any `T: ProjectGeneric + Send + Sync + Debug`
/// automatically satisfies `ProjectGenericBox`.