pub struct GlobalGaussNewton {
pub iterations: usize,
pub damping: f64,
pub maximum_cg_iterations: usize,
pub cg_relative_tolerance: f64,
pub maximum_line_search_steps: usize,
pub line_search_reduction: f64,
pub line_search_sufficient_decrease: f64,
pub epsilon: f64,
}Expand description
Matrix-free damped Gauss–Newton reconstruction of a fixed-pupil FPM object.
§Method
The solver minimizes the full-stack, frame-weighted mean amplitude-MSE objective in intrinsic intensity units. Known detector gain and background are removed before forming residuals, masks omit pixels, and zero-weight frames contribute neither residuals nor derivatives. Incoherently multiplexed frames use one detector residual whose analytic derivative contains every contributing coherent source mode.
Each outer iteration linearizes the amplitude residual at the current
centered object spectrum and solves
(J^T J + damping * diag(C)) d = -J^T r with preconditioned conjugate
gradients. J and J^T are applied analytically under the real inner
product on complex arrays. C is a floored pupil-power Fourier-coverage
approximation used for both damping and Jacobi preconditioning. Armijo
backtracking accepts a step only when the same full-data objective
decreases sufficiently.
Frames are processed for every gradient, normal-operator, and line-search evaluation. The implementation stores a fixed number of object-sized vectors and only the coherent fields of the current multiplexed frame; it never forms a Jacobian or Hessian and does not retain curvature across outer iterations. Consequently it supports lazy measurements and exact iteration-boundary checkpoint resume, but each iteration is substantially more expensive than a sequential projection or one gradient pass.
The pupil, frame response, generic source corrections, and physical model
are treated as fixed during one step. The absence of persistent curvature
permits use as the object phase of
crate::algorithms::JointReconstruction, whose subsequent physical phase
recompiles the model before the next fresh linearization.
§Failure behavior
Configuration validation rejects non-positive limits or damping and tolerances outside their documented open intervals. A step also rejects an incomplete global batch or unrelated algorithm auxiliary state. Non-finite products, non-positive conjugate-gradient curvature, a non-descent direction, or an exhausted line search return an error without committing a trial object.
§Example
use fpm_rs::{
Result,
algorithms::{GlobalGaussNewton, ReconstructionAlgorithm},
measurements::MeasurementRead,
reconstruction::ReconstructionProblem,
};
let result = GlobalGaussNewton::default()
.iterations(10)
.damping(1e-3)
.maximum_cg_iterations(8)
.run(problem)?;
assert_eq!(result.trace.iterations.len(), 10);§References
L.-H. Yeh, J. Dong, J. Zhong, L. Tian, M. Chen, G. Tang, M. Soltanolkotabi, and L. Waller, “Experimental robustness of Fourier ptychography phase retrieval algorithms,” Optics Express 23(26), 33214–33240 (2015). That work forms exact CR-calculus Hessians for several objectives; this implementation keeps only the positive-semidefinite Gauss–Newton part of the amplitude residual and applies it without materializing a matrix.
Matrix-free second-order ptychographic optimization is also demonstrated by S. Kandel, S. Maddali, Y. S. G. Nashed, S. O. Hruszkewycz, C. Jacobsen, and M. Allain, “Efficient ptychographic phase retrieval via a matrix-free Levenberg–Marquardt algorithm,” Optics Express 29(15), 23019–23055 (2021). That work treats diffraction-plane ptychography with automatic differentiation, whereas this solver uses analytic products for the crate’s image-plane FPM model.
Fields§
§iterations: usizeNumber of complete global object updates.
damping: f64Positive coverage-scaled diagonal damping coefficient.
maximum_cg_iterations: usizeMaximum matrix-free conjugate-gradient iterations per outer update.
cg_relative_tolerance: f64Relative linear-residual tolerance for conjugate-gradient termination.
maximum_line_search_steps: usizeMaximum full-data trial-objective evaluations per outer update.
line_search_reduction: f64Multiplicative trial-step reduction in (0, 1).
line_search_sufficient_decrease: f64Armijo sufficient-decrease coefficient in (0, 1).
epsilon: f64Positive floor for dark-field derivatives and Fourier coverage.
Implementations§
Source§impl GlobalGaussNewton
impl GlobalGaussNewton
Sourcepub fn iterations(self, iterations: usize) -> Self
pub fn iterations(self, iterations: usize) -> Self
Sets the positive number of global object updates.
Sourcepub fn damping(self, damping: f64) -> Self
pub fn damping(self, damping: f64) -> Self
Sets the finite positive coverage-scaled damping coefficient.
Sourcepub fn maximum_cg_iterations(self, iterations: usize) -> Self
pub fn maximum_cg_iterations(self, iterations: usize) -> Self
Sets the positive maximum conjugate-gradient iteration count.
Sourcepub fn cg_relative_tolerance(self, tolerance: f64) -> Self
pub fn cg_relative_tolerance(self, tolerance: f64) -> Self
Sets the relative conjugate-gradient residual tolerance in (0, 1).
Sourcepub fn maximum_line_search_steps(self, steps: usize) -> Self
pub fn maximum_line_search_steps(self, steps: usize) -> Self
Sets the positive maximum number of trial-objective evaluations.
Sourcepub fn line_search_reduction(self, reduction: f64) -> Self
pub fn line_search_reduction(self, reduction: f64) -> Self
Sets the multiplicative backtracking reduction in (0, 1).
Sourcepub fn line_search_sufficient_decrease(self, coefficient: f64) -> Self
pub fn line_search_sufficient_decrease(self, coefficient: f64) -> Self
Sets the Armijo sufficient-decrease coefficient in (0, 1).
Trait Implementations§
Source§impl Clone for GlobalGaussNewton
impl Clone for GlobalGaussNewton
Source§fn clone(&self) -> GlobalGaussNewton
fn clone(&self) -> GlobalGaussNewton
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for GlobalGaussNewton
impl Debug for GlobalGaussNewton
Source§impl Default for GlobalGaussNewton
impl Default for GlobalGaussNewton
Source§impl ReconstructionAlgorithm for GlobalGaussNewton
impl ReconstructionAlgorithm for GlobalGaussNewton
Source§type IterationMetrics = GlobalGaussNewtonIterationMetrics
type IterationMetrics = GlobalGaussNewtonIterationMetrics
Source§fn validate(&self) -> Result<()>
fn validate(&self) -> Result<()>
Source§fn step<M: MeasurementRead>(
&mut self,
problem: &ReconstructionProblem<M>,
state: &mut ReconstructionState,
batch: &Batch,
_iteration: usize,
) -> Result<StepOutput<Self::IterationMetrics>>
fn step<M: MeasurementRead>( &mut self, problem: &ReconstructionProblem<M>, state: &mut ReconstructionState, batch: &Batch, _iteration: usize, ) -> Result<StepOutput<Self::IterationMetrics>>
state for one scheduled batch in zero-based iteration.Source§fn iterations(&self) -> usize
fn iterations(&self) -> usize
Source§fn batch_size(&self) -> usize
fn batch_size(&self) -> usize
Source§fn validate_problem<M: MeasurementRead>(
&self,
_problem: &ReconstructionProblem<M>,
) -> Result<()>
fn validate_problem<M: MeasurementRead>( &self, _problem: &ReconstructionProblem<M>, ) -> Result<()>
problem.Source§fn initialize<M: MeasurementRead>(
&self,
problem: &ReconstructionProblem<M>,
) -> Result<ReconstructionState>
fn initialize<M: MeasurementRead>( &self, problem: &ReconstructionProblem<M>, ) -> Result<ReconstructionState>
problem.Source§fn initialize_with_backend<M: MeasurementRead>(
&self,
problem: &ReconstructionProblem<M>,
backend: Arc<dyn Backend>,
) -> Result<ReconstructionState>
fn initialize_with_backend<M: MeasurementRead>( &self, problem: &ReconstructionProblem<M>, backend: Arc<dyn Backend>, ) -> Result<ReconstructionState>
backend.Source§fn canonicalize_state<M: MeasurementRead>(
&self,
_problem: &ReconstructionProblem<M>,
_state: &mut ReconstructionState,
) -> Result<()>
fn canonicalize_state<M: MeasurementRead>( &self, _problem: &ReconstructionProblem<M>, _state: &mut ReconstructionState, ) -> Result<()>
Source§fn supports_joint_reconstruction(&self) -> bool
fn supports_joint_reconstruction(&self) -> bool
Source§fn run<M: MeasurementRead>(
self,
problem: &ReconstructionProblem<M>,
) -> Result<ReconstructionResult>where
Self: Sized,
fn run<M: MeasurementRead>(
self,
problem: &ReconstructionProblem<M>,
) -> Result<ReconstructionResult>where
Self: Sized,
Source§fn run_with_callbacks<M: MeasurementRead>(
self,
problem: &ReconstructionProblem<M>,
callbacks: Vec<Box<dyn Callback>>,
) -> Result<ReconstructionResult>where
Self: Sized,
fn run_with_callbacks<M: MeasurementRead>(
self,
problem: &ReconstructionProblem<M>,
callbacks: Vec<Box<dyn Callback>>,
) -> Result<ReconstructionResult>where
Self: Sized,
callbacks at their declared hooks.Source§fn run_from_checkpoint<M: MeasurementRead>(
self,
problem: &ReconstructionProblem<M>,
checkpoint: ReconstructionCheckpoint,
) -> Result<ReconstructionResult>where
Self: Sized,
fn run_from_checkpoint<M: MeasurementRead>(
self,
problem: &ReconstructionProblem<M>,
checkpoint: ReconstructionCheckpoint,
) -> Result<ReconstructionResult>where
Self: Sized,
problem.Auto Trait Implementations§
impl Freeze for GlobalGaussNewton
impl RefUnwindSafe for GlobalGaussNewton
impl Send for GlobalGaussNewton
impl Sync for GlobalGaussNewton
impl Unpin for GlobalGaussNewton
impl UnsafeUnpin for GlobalGaussNewton
impl UnwindSafe for GlobalGaussNewton
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more