Structure of utilized Pytrees

All methods and algorithms utilize three major pytrees descent_state, measurement_info and descent_info. All of these are instances of pulsedjax.utilities.MyNamespace. This custom type is used in order to dynamically define the structure of pytree instances via the MyNamespace.expand() method, which provides flexibility during developement. Unfortunately this flexibility easily leads to somewhat messy and opaque datastructures. Here an attempt is made to provide a rough overview.

Generally measurement_info and descent_info are treated as static/constant, while descent_state contains all variables which may be changed by an algorithm.

Descent State

As stated above descent_state contains all (possibly) dynamic variables of an algorithm. Thus its content depends on the algorithm in question. It always contains the current guesses descent_state.population. The content and structure of which is again dependent on the algorithm.
In all algorithms the pulse(-parameters) are always described/stored in the frequency domain inside population. For algorithms which include randomization descent_state also holds a PRNG-key.

For classical algorithms descent_state may additionally contain information from the previous iteration(s) which are utilized by various nonlinear optimization approaches. In contrast in general algorithms it may contain dynamic variables/containers from optimistix or evosax.
The substructure of many variables in descent_state is subdivided into .pulse and .gate, since in the case of doubleblind retrievals twice the information needs to be stored.

Below is an example of the descent_state structure used by DifferentialEvolution.

descent_state
├── population
│   ├── pulse
│   │   ├── amp
│   │   └── phase
│   └── gate
│       ├── amp
│       └── phase
├── best_individual
│   ├── pulse
│   │   ├── amp
│   │   └── phase
│   └── gate
│       ├── amp
│       └── phase
├── mu 
└── key

Measurement Info

The measurement_info object contains all information related to the measurement method as well es derived parameters used for the retrieval. Thus it almost never depends on the algorithm used. If it varies it mainly does so with the measurement method.
Examples of its contents are time, frequency, measured_trace, nonlinear_method, spectral_amplitude (pulse spectrum if provided) and more.

Descent Info

The structure and content of descent_info is purely algorithm dependent. It holds all parameters that are/may be used by the algorithm. For a DifferentialEvolution this may for example include crossover_strategy, mutation_strategy crossover_rate, mutation_rate among other things.

Below is an example of the structure of descent_info for the PtychographicIterativeEngine.

descent_info
├── measured_spectrum_is_provided
│	├── pulse
│	└── gate
├── eta_spectral_amplitude
├── optimize_calibration_curve
│	├── _local
│	└── _global
├── population_size 
├── gamma
│	├── _local 
│	└── _global
├── alpha 
├── pie_method
├── conjugate_gradients
│	├── _local
│	└── _global
├── linesearch_params
│	├── linesearch
│	├── c1
│	├── c2
│	├── max_steps
│	└── delta_gamma
├── newton
│	├── _local
│	├── _global
│	├── linalg_solver
│	├── lambda_lm
│	└── lbfgs_memory
├── s_prime_params
│	├── _local
│	├── _global
│	├── number_of_iterations 
│	├── r_gradient
│	├── r_newton
│	└── weights
├── xi 
└── adaptive_scaling
	├── _local
	│	├── order
	│	└── factor
	└── _global
		├── order
		└── factor

Final Result

All algorithms perform a post processing step in which information from the final descent_state is extracted, analyzed and used to create the final_result object which is returned by algorithm.run(). The structure of this object is show below.

final_result
├── time
├── frequency
├── pulses
│   ├── pulse_t
│   ├── pulse_f
│   ├── gate_t
│   ├── gate_f
│   └── idx
├── idx_best_individual
├── x_arr
├── frequency_exp
├── trace
├── measured_trace
├── mu
│   ├── _local
│   └── _global
└── error_arr