homodyne.core.models

Object-oriented interface to the physical models for homodyne scattering analysis. Every model wraps the JAX-compiled functions in homodyne.core.jax_backend and exposes a uniform interface through the PhysicsModelBase abstract base class.

For the underlying physics, including the full derivation of the \(g_1\) and \(g_2\) correlation functions, see Theory & Physics.


Physical Model Summary

The measured intensity correlation function is:

\[c_2(\varphi, t_1, t_2) = \text{offset} + \text{contrast} \times [c_1(\varphi, t_1, t_2)]^2\]

where the field correlation function factorises as:

\[c_1(\varphi, t_1, t_2) = c_1^\text{diff}(t_1, t_2) \times c_1^\text{shear}(\varphi, t_1, t_2)\]

Time-dependent transport coefficients:

\[ \begin{align}\begin{aligned}D(t) = D_0 \cdot t^\alpha + D_\text{offset}\\\dot\gamma(t) = \dot\gamma_0 \cdot t^\beta + \dot\gamma_\text{offset}\end{aligned}\end{align} \]

Mode

Parameters

Count

static

\(D_0, \alpha, D_\text{offset}\)

3

laminar_flow

\(D_0, \alpha, D_\text{offset}, \dot\gamma_0, \beta,\) \(\dot\gamma_\text{offset}, \varphi_0\)

7


PhysicsModelBase

Abstract base class defining the interface all physical models must implement.

class homodyne.core.models.PhysicsModelBase[source]

Bases: ABC

Abstract base class for all physical models.

Defines the interface that all models must implement and provides common functionality for parameter management and validation.

__init__(name, parameter_names)[source]

Initialize base model.

Parameters:
  • name (str) – Model name for identification

  • parameter_names (list[str]) – List of parameter names in order

abstractmethod compute_g1(params, t1, t2, phi, q, L, dt=None)[source]

Compute g1 correlation function for this model.

Return type:

Array

abstractmethod get_parameter_bounds()[source]

Get parameter bounds for optimization.

Return type:

list[tuple[float, float]]

abstractmethod get_default_parameters()[source]

Get default parameter values.

Return type:

Array

validate_parameters(params)[source]

Validate parameter values against bounds and constraints.

Return type:

bool

get_parameter_dict(params)[source]

Convert parameter array to named dictionary.

Return type:

dict[str, float]


DiffusionModel

Implements the diffusion-only contribution to \(g_1\). Used as a building block by both CombinedModel and in static analysis mode.

class homodyne.core.models.DiffusionModel[source]

Bases: PhysicsModelBase

Anomalous diffusion model: D(t) = D₀ t^α + D_offset

Parameters: - D₀: Reference diffusion coefficient [Ų/s] - α: Diffusion time-dependence exponent [-] - D_offset: Baseline diffusion [Ų/s]

Physical interpretation: - α = 0: Normal diffusion (Brownian motion) - α > 0: Super-diffusion (enhanced mobility) - α < 0: Sub-diffusion (restricted mobility) - D_offset: Residual diffusion at t=0

__init__()[source]

Initialize base model.

Parameters:
  • name – Model name for identification

  • parameter_names – List of parameter names in order

compute_g1(params, t1, t2, phi, q, L, dt=None)[source]

Compute diffusion contribution to g1.

g₁_diff = exp[-q²/2 ∫|t₂-t₁| D(t’)dt’]

Return type:

Array

get_parameter_bounds()[source]

Standard bounds for diffusion parameters.

Return type:

list[tuple[float, float]]

get_default_parameters()[source]

Default values for typical XPCS measurements.

Return type:

Array

Usage Example

import jax.numpy as jnp
from homodyne.core.models import DiffusionModel

model = DiffusionModel()

# Parameters: [D0, alpha, D_offset]
params = jnp.array([100.0, 0.5, 0.01])
t1 = jnp.linspace(0.001, 1.0, 50)
t2 = jnp.linspace(0.001, 1.0, 50)

g1 = model.compute_g1(params, t1, t2, phi=jnp.array([0.0]), q=0.01, L=1000.0)

ShearModel

Implements the shear-flow contribution to \(g_1\):

\[c_1^\text{shear}(\varphi, t_1, t_2) = \left[\operatorname{sinc}\!\left(\Phi(\varphi, t_1, t_2)\right)\right]^2\]

where \(\Phi = \frac{1}{2\pi} q L \cos(\varphi_0 - \varphi) \int_{|t_2-t_1|} \dot\gamma(t') \, dt'\).

class homodyne.core.models.ShearModel[source]

Bases: PhysicsModelBase

Time-dependent shear model: γ̇(t) = γ̇₀ t^β + γ̇_offset

Parameters: - γ̇₀: Reference shear rate [s⁻¹] - β: Shear rate time-dependence exponent [-] - γ̇_offset: Baseline shear rate [s⁻¹] - φ₀: Angular offset parameter [degrees]

Physical interpretation: - β = 0: Constant shear rate (steady shear) - β > 0: Increasing shear rate with time - β < 0: Decreasing shear rate with time - φ₀: Preferred flow direction angle

__init__()[source]

Initialize base model.

Parameters:
  • name – Model name for identification

  • parameter_names – List of parameter names in order

compute_g1(params, t1, t2, phi, q, L, dt=None)[source]

Compute shear contribution to g1.

g₁_shear = [sinc(Φ)]² where Φ = (qL/2π) cos(φ₀-φ) ∫|t₂-t₁| γ̇(t’) dt’

Return type:

Array

get_parameter_bounds()[source]

Standard bounds for shear parameters.

Return type:

list[tuple[float, float]]

get_default_parameters()[source]

Default values for typical shear flow.

Return type:

Array


CombinedModel

Full laminar-flow model combining diffusion and shear contributions. This is the model used when analysis_mode="laminar_flow".

class homodyne.core.models.CombinedModel[source]

Bases: PhysicsModelBase, GradientCapabilityMixin, BenchmarkingMixin, OptimizationRecommendationMixin

Combined diffusion + shear model for complete homodyne analysis.

This is the full model used for laminar flow analysis with both anomalous diffusion and time-dependent shear.

Parameters (7 total): - D₀, α, D_offset: Diffusion parameters - γ̇₀, β, γ̇_offset: Shear parameters - φ₀: Angular offset parameter

For static analysis, only the first 3 diffusion parameters are used.

Mixin capabilities: - GradientCapabilityMixin: gradient/Hessian access with backend selection - BenchmarkingMixin: performance benchmarking and accuracy validation - OptimizationRecommendationMixin: optimization guidance and model info

__init__(analysis_mode='laminar_flow')[source]

Initialize combined model.

Parameters:

analysis_mode (str) – “static” or “laminar_flow”

compute_g1(params, t1, t2, phi, q, L, dt=None)[source]

Compute total g1 = g1_diffusion × g1_shear.

Return type:

Array

compute_g1_batch(params, t1_batch, t2_batch, phi_batch, q, L, dt=None)[source]

Compute g1 for a batch of points using vmap.

Performance Optimization (Spec 001 - FR-006, T041): Vectorized computation using jax.vmap for batched point-wise g1 calculation, replacing Python loops.

Parameters:
  • params (Array) – Physical parameters array

  • t1_batch (Array) – Batch of t1 values, shape (n_points,)

  • t2_batch (Array) – Batch of t2 values, shape (n_points,)

  • phi_batch (Array) – Batch of phi values, shape (n_points,)

  • q (float) – Scattering wave vector magnitude [Å⁻¹]

  • L (float) – Sample-detector distance (stator_rotor_gap) [Å]

  • dt (float | None) – Time step from configuration [s]

Returns:

Batch of g1 values, shape (n_points,)

Return type:

Array

compute_g2(params, t1, t2, phi, q, L, contrast, offset, dt)[source]

Compute g2 with scaled fitting: g₂ = offset + contrast × [g₁]²

Parameters:
  • params (Array) – Physical parameters array

  • t1 (Array) – Time grids for correlation calculation

  • t2 (Array) – Time grids for correlation calculation

  • phi (Array) – Scattering angles in degrees

  • q (float) – Scattering wave vector magnitude [Å⁻¹]

  • L (float) – Sample-detector distance (stator_rotor_gap) [Å]

  • contrast (float) – Contrast parameter (β in literature)

  • offset (float) – Baseline offset

  • dt (float) – Time step from configuration [s] (REQUIRED). Fallback estimation has been removed for safety.

Returns:

g2 correlation function

Return type:

Array

Raises:
compute_chi_squared(params, data, sigma, t1, t2, phi, q, L, contrast, offset)[source]

Compute chi-squared goodness of fit.

Return type:

float

get_parameter_bounds()[source]

Get bounds appropriate for analysis mode.

Return type:

list[tuple[float, float]]

get_default_parameters()[source]

Get default parameters appropriate for analysis mode.

Return type:

Array

Usage Example

import jax.numpy as jnp
from homodyne.core.models import CombinedModel

model = CombinedModel()

# Parameters: [D0, alpha, D_offset, gamma_dot0, beta, gamma_dot_t_offset, phi0]
params = jnp.array([100.0, 0.5, 0.01, 1e-3, 0.0, 0.0, 0.0])
phi = jnp.array([0.0, 45.0, 90.0, 135.0])   # degrees
t1 = jnp.linspace(0.001, 1.0, 50)
t2 = jnp.linspace(0.001, 1.0, 50)

g1 = model.compute_g1(params, t1, t2, phi=phi, q=0.01, L=1000.0)
g2 = model.compute_g2(params, t1, t2, phi=phi, q=0.01, L=1000.0,
                      contrast=0.5, offset=1.0)

Module-level factory

homodyne.core.models.create_model(analysis_mode)[source]

Factory function to create appropriate model for analysis mode.

Parameters:

analysis_mode (str) – “static” or “laminar_flow”

Return type:

CombinedModel

Returns:

Configured CombinedModel instance

Physical Models for Homodyne

Object-oriented interface to the physical models implemented in the JAX backend. Provides structured access to diffusion, shear, and combined models with parameter validation and configuration management.

Homodyne Model

The measured intensity correlation uses per-angle scaling:

c2(φ, t₁, t₂) = offset + contrast × [c1(φ, t₁, t₂)]²

with a separable field correlation function:

c1(φ, t₁, t₂) = c1_diff(t₁, t₂) × c1_shear(φ, t₁, t₂)

Diffusion contribution:

c1_diff(t₁, t₂) = exp[-(q² / 2) ∫|t₂ - t₁| D(t’) dt’]

Shear contribution:

c1_shear(φ, t₁, t₂) = [sinc(Φ(φ, t₁, t₂))]² Φ(φ, t₁, t₂) = (1 / 2π) · q · L · cos(φ₀ - φ) · ∫|t₂ - t₁| γ̇(t’) dt’

Time-dependent transport coefficients:

D(t) = D₀ · t^α + D_offset γ̇(t) = γ̇₀ · t^β + γ̇_offset

Parameter sets: - Static mode (3 params): D₀, α, D_offset (γ̇₀, β, γ̇_offset, φ₀ fixed/irrelevant) - Laminar flow (7 params): D₀, α, D_offset, γ̇₀, β, γ̇_offset, φ₀

Experimental parameters: - q: scattering wavevector magnitude [Å⁻¹] - L: gap/characteristic length [Å] - φ: scattering angle [degrees] - dt: frame time step [s]

homodyne.core.models.get_available_models()[source]

Get list of available analysis modes.

Return type:

list[str]