TorchOptics

repository·main·Indexed 41 days ago

https://github.com/matthewfilipovich/torchoptics

A GPU-accelerated, fully differentiable Python library for simulating optical systems using Fourier optics. Built on PyTorch, it enables the joint optimization of optical hardware and machine learning models through automatic differentiation. Key features include support for lenses, phase/amplitude modulators, and various spatial profiles (e.g., Hermite-Gaussian, Laguerre-Gaussian), as well as tools for inverse design of optical systems.

Tokens
28.3K
Snippets
97
Records
118
Agent score
52%

What's inside TorchOptics

  1. Overview of TorchOptics features

    main

    TorchOptics is a Python library for simulating optical systems using Fourier optics, built on top of PyTorch. It is designed for end-to-end optimization of optical hardware jointly with machine learning models.

    Key capabilities include:

    • Differentiable Wave Optics: Model and optimize systems using Fourier optics.
    • PyTorch Integration: Leverages GPU acceleration, batch processing, and automatic differentiation.
    • Optical Elements: Support for lenses, phase/amplitude modulators, detectors, polarizers, and more.
    • Spatial Profiles: Includes Hermite-Gaussian, Laguerre-Gaussian, Zernike modes, and gratings.
    • Polarization & Coherence: Simulation of polarized light and fields with arbitrary spatial coherence.
  2. Explore optical phenomena and diffractive optical elements

    main

    The examples/optical_phenomena directory contains demonstrations of various optical phenomena and diffractive optical elements (DOEs) using torchoptics. These examples cover:

    • Interference patterns: Visualizing how waves interact.
    • Zone plates: Simulating diffractive focusing elements.
    • The Talbot effect: Demonstrating self-imaging of periodic structures.
    • Grating dispersion: Modeling the spreading of light through gratings.
  3. Use TorchOptics for Optimization & Inverse Design

    main
    TorchOptics provides differentiable optics examples that leverage gradient-based optimization. You can use these capabilities to design phase elements and multi-layer diffractive systems for various optical applications. The library is designed to support inverse design workflows where system parameters are optimized to meet specific performance targets.
  4. Explore optical system examples in TorchOptics

    main

    The examples/optical_systems directory contains implementations and demonstrations of multi-element optical systems and instruments. You can use these examples as templates or reference implementations for modeling complex setups such as:

    • Lenses: Single or multi-element lens systems.
    • Telescopes: Compound optical instruments.
    • Interferometers: Systems for measuring wave interference.
    • Holographic Beam Shapers: Systems utilizing holographic elements to manipulate beam profiles.
  5. What is Spatial Coherence in TorchOptics?

    main

    In torchoptics, coherent light (like a laser) is modeled by a single complex field, whereas partially coherent light (like LEDs or thermal sources) requires a statistical description called the mutual coherence function ($\Gamma$).

    The SpatialCoherence class provides this statistical description, allowing for physically accurate simulations of sources that cannot be modeled by a single wavefront.

    Key Concepts:

    • Mutual Coherence Function ($\Gamma$): Encodes the statistical correlation between two spatial points $(x_1, y_1)$ and $(x_2, y_2)$.
    • Intensity ($I$): The diagonal of the coherence function, $\Gamma(x, y, x, y)$, represents the time-averaged intensity.
    • Memory Complexity: The coherence matrix is stored as a 4D complex tensor of shape (H, W, H, W). Because this scales as $O(N^4)$, it is recommended to keep grid sizes small (typically 20–50 points per dimension) or use GPU acceleration for larger grids.
  6. How the torchoptics.System class works

    main

    The torchoptics.System class models an optical system as an ordered sequence of elements along the optical axis. It behaves similarly to torch.nn.Sequential, where propagation between elements is handled automatically. Elements are positioned along the axis based on their z attribute. During a forward pass, the system propagates a field through every element in order of increasing z and returns the field immediately after the last element. Elements with a z position strictly less than the input field's starting z are skipped, while elements at exactly the starting z are applied.

    import torchoptics
    from torchoptics import Field, System
    from torchoptics.elements import Lens
    
    # Elements are ordered by their z position
    system = System(
        Lens(shape=(1000, 1000), f=200e-3, z=1 * 200e-3),
        Lens(shape=(1000, 1000), f=200e-3, z=3 * 200e-3),
    )
    
    input_field = Field(torchoptics.profiles.gaussian(1000, waist_radius=1e-3), z=0)
    output_field = system(input_field)
  7. Understand the `Field` class

    main

    The Field class is the central object in TorchOptics. It represents a complex-valued wavefront sampled on a 2D planar grid at a specific position along the optical axis.

    Fields support batching: the underlying data tensor can have shape (..., H, W), where leading dimensions are treated as batch dimensions. All operations like propagation and analysis will respect these batch dimensions.

    import torch
    from torchoptics import Field
    
    # Create a batched field (4 batches, 300x300 grid)
    batch_data = torch.randn(4, 300, 300, dtype=torch.cdouble)
    batch_field = Field(batch_data)
  8. Work with polarized fields in TorchOptics

    main

    Polarized fields are represented by data tensors with the shape (..., 3, H, W), where the dimension of size 3 corresponds to the $x$, $y$, and $z$ polarization components. Polarization elements in TorchOptics operate on these fields by applying a $3 \times 3$ Jones matrix $J$ at every grid point:

    $$\begin{pmatrix} E_x' \ E_y' \ E_z' \end{pmatrix} = J(x, y) \begin{pmatrix} E_x \ E_y \ E_z \end{pmatrix}$$

    To use polarized elements, you must first construct a polarized field (e.g., by initializing a tensor with shape (3, H, W) and wrapping it in a Field object).

    import torch
    from torchoptics import Field
    
    # Example: Creating an x-polarized Gaussian beam
    shape = (512, 512)
    polarized_data = torch.zeros(3, *shape, dtype=torch.cdouble)
    # Assume gaussian() is available to populate the x-component
    polarized_data[0] = gaussian(shape, waist_radius=1.5e-3)
    polarized_field = Field(polarized_data)
  9. Representing polarized fields in TorchOptics

    main

    To handle polarized light, TorchOptics extends the Field class to represent the electric field vector using three complex components corresponding to the $x$, $y$, and $z$ directions.

    In paraxial optics, the $z$ component is typically zero, and energy is carried by the transverse $x$ and $y$ components. A polarized field is represented by a data tensor of shape (3, H, W), where:

    • Index 0 is the $x$-component.
    • Index 1 is the $y$-component.
    • Index 2 is the $z$-component.
    import torch
    import torchoptics
    from torchoptics import Field
    from torchoptics.profiles import gaussian
    
    torchoptics.set_default_spacing(10e-6)
    torchoptics.set_default_wavelength(700e-9)
    shape = 200
    
    # Create an x-polarized Gaussian beam (only the x-component is non-zero)
    data = torch.zeros(3, shape, shape, dtype=torch.cdouble)
    data[0] = gaussian(shape, waist_radius=500e-6)
    x_pol = Field(data)