eispy2d.discretization package#

Submodules#

eispy2d.discretization.collocation module#

Collocation Method for Electromagnetic Inverse Scattering Discretization

This module implements the Collocation Method for discretizing electromagnetic inverse scattering problems. The collocation method is a numerical technique that uses trial functions and collocation points to approximate the solution of integral equations in electromagnetic scattering problems.

The module provides the Collocation class for method configuration and several optimized kernel functions for efficient computation of matrix operations commonly used in electromagnetic inverse scattering algorithms.

Classes#

CollocationExtends discretization.Discretization

Main collocation method implementation for electromagnetic discretization

Functions#

kernel_GSE(GS, E) : Compute kernel matrix for scattered field Green’s function kernel_GSX(GS, X) : Compute kernel matrix for scattered field with contrast kernel_GDX(GD, X) : Compute kernel matrix for domain Green’s function with contrast kernel_GDE(GD, E) : Compute kernel matrix for domain Green’s function with field lhs_XEi(X, Ei) : Compute left-hand side matrix for contrast and incident field

Constants#

TRIAL_FUNCTIONstr

Dictionary key for trial function type

ELEMENTSstr

Dictionary key for discretization elements

Notes

The collocation method approximates the solution using basis functions and enforces the integral equation at specific collocation points. This approach is particularly effective for electromagnetic scattering problems where the Green’s function matrices can be computed efficiently.

All kernel functions are optimized using Numba’s just-in-time compilation for improved performance in iterative reconstruction algorithms.

Examples

>>> # Create collocation discretization
>>> collocation = Collocation(configuration=config,
...                          trial='pulse',
...                          elements=(64, 64))
>>> # Use kernel functions for matrix operations
>>> K_GSE = kernel_GSE(GS_matrix, E_field)
>>> K_GSX = kernel_GSX(GS_matrix, contrast)
class eispy2d.discretization.collocation.Collocation(configuration=None, trial=None, elements=None, name=None, alias='clc', import_filename=None, import_filepath='')#

Bases: Discretization

Collocation method for electromagnetic inverse scattering discretization.

This class implements the collocation method for discretizing electromagnetic inverse scattering problems. The method uses trial functions and collocation points to approximate the solution of integral equations, providing an efficient framework for electromagnetic reconstruction algorithms.

The collocation method is particularly well-suited for problems where the Green’s function can be computed analytically or semi-analytically, making it computationally efficient for iterative reconstruction methods.

Parameters:
  • configuration (configuration.Configuration, optional) – Problem configuration object containing geometry and material properties

  • trial (str, optional) – Type of trial function to use (e.g., ‘pulse’, ‘linear’, ‘cubic’)

  • elements (int or tuple of int, optional) – Number of discretization elements. If int, creates square grid (N×N). If tuple, creates rectangular grid (NY×NX)

  • name (str, optional) – Custom name for the discretization method

  • alias (str, default='clc') – Short alias for the method used in file operations

  • import_filename (str, optional) – Filename to import configuration from

  • import_filepath (str, default='') – Path to import file

trial#

Type of trial function used

Type:

str

elements#

Grid dimensions (NY, NX)

Type:

tuple of int

name#

Descriptive name of the discretization method

Type:

str

alias#

Short alias for the method

Type:

str

copy(new=None)#

Create a copy of the collocation instance

save(file_path='')#

Save configuration to file

importdata(file_name, file_path='')#

Import configuration from file

Raises:

error.MissingInputError – If required elements parameter is not provided

Notes

The collocation method discretizes the electromagnetic integral equation by choosing specific collocation points where the equation is enforced exactly. This approach transforms the continuous integral equation into a system of linear equations that can be solved numerically.

Trial functions commonly used include: - pulse: Piecewise constant functions - linear: Piecewise linear functions - cubic: Piecewise cubic functions

Examples

>>> # Create square grid collocation
>>> collocation = Collocation(configuration=config,
...                          trial='pulse',
...                          elements=64)
>>> # Create rectangular grid collocation
>>> collocation = Collocation(configuration=config,
...                          trial='linear',
...                          elements=(32, 64))
>>> # Import from saved configuration
>>> collocation = Collocation(import_filename='collocation_config.pkl')
>>> # Print method information
>>> print(collocation)
Collocation Method (64x64), trial function: pulse
__init__(configuration=None, trial=None, elements=None, name=None, alias='clc', import_filename=None, import_filepath='')#

Initialize the Collocation discretization method.

Parameters:
  • configuration (Configuration, optional) – Problem configuration object.

  • trial (str, optional) – Type of trial function (e.g., ‘pulse’, ‘linear’, ‘cubic’).

  • elements (int or tuple of int) – Number of discretization elements. If int, creates square grid (N×N). If tuple, creates rectangular grid (NY×NX).

  • name (str, optional) – Custom name for the discretization method.

  • alias (str, default='clc') – Short alias for file operations.

  • import_filename (str, optional) – Filename to import configuration from.

  • import_filepath (str, default='') – Path to import file.

__str__()#

Return string representation of the collocation method.

Creates a formatted string containing the method configuration including discretization details and alias.

Returns:

Formatted string representation of the collocation method

Return type:

str

Examples

>>> print(collocation)
Collocation Method (64x64), trial function: pulse
Alias: clc
copy(new=None)#

Create a copy of the collocation instance.

Creates either a new independent instance or copies the configuration to an existing instance.

Parameters:

new (Collocation or None, default=None) – If None, creates a new independent instance If provided, copies configuration to this instance

Returns:

New instance if new=None, otherwise None

Return type:

Collocation or None

Examples

>>> # Create independent copy
>>> collocation_copy = collocation.copy()
>>> # Copy configuration to existing instance
>>> new_collocation = Collocation(configuration=config,
...                              trial='pulse',
...                              elements=(32, 32))
>>> collocation.copy(new_collocation)
importdata(file_name, file_path='')#

Import collocation configuration from a saved file.

Loads a previously saved collocation configuration including trial function type and discretization elements.

Parameters:
  • file_name (str) – Name of the file to import from

  • file_path (str, default='') – Path to the file location

Examples

>>> collocation = Collocation()
>>> collocation.importdata('collocation_config.pkl', '/path/to/files/')
save(file_path='')#

Save the collocation configuration to a file.

Saves the complete collocation method configuration including trial function type and discretization elements using pickle serialization.

Parameters:

file_path (str, default='') – Path where the configuration file will be saved

Examples

>>> collocation.save('/path/to/save/')
>>> collocation.save()  # Save in current directory
eispy2d.discretization.collocation.kernel_GDE(GD, E)#

Compute kernel matrix for domain Green’s function with electric field.

Computes the kernel matrix for the domain interaction using the Green’s function matrix GD and electric field E. This creates a 3D kernel matrix used in electromagnetic inverse scattering computations involving field interactions.

Parameters:
  • GD (numpy.ndarray) – Green’s function matrix for domain interaction with shape (N, N) where N is the number of discretization elements

  • E (numpy.ndarray) – Electric field matrix with shape (N, NS) where N is the number of discretization elements and NS is the number of sources

Returns:

Kernel matrix K with shape (N, N, NS) containing the computed kernel values for electromagnetic field interactions

Return type:

numpy.ndarray

Notes

The kernel matrix is computed as: K[n, m, s] = GD[n, m] * E[m, s]

This 3D kernel matrix represents the interaction between the domain Green’s function and the electric field for all source configurations simultaneously, which is useful for multi-source electromagnetic inverse scattering problems.

Examples

>>> GD = np.random.complex128((4096, 4096))  # 64x64 grid
>>> E = np.random.complex128((4096, 16))     # 64x64 grid, 16 sources
>>> K = kernel_GDE(GD, E)
>>> print(K.shape)  # (4096, 4096, 16)
>>> # Access kernel for specific source
>>> K_source_0 = K[:, :, 0]  # Kernel for first source
>>> print(K_source_0.shape)  # (4096, 4096)
eispy2d.discretization.collocation.kernel_GDX(GD, X)#

Compute kernel matrix for domain Green’s function with contrast.

Computes the kernel matrix for the domain interaction using the Green’s function matrix GD and contrast function X. This creates the modified identity matrix (I - GD*X) used in electromagnetic inverse scattering formulations.

Parameters:
  • GD (numpy.ndarray) – Green’s function matrix for domain interaction with shape (N, N) where N is the number of discretization elements

  • X (numpy.ndarray) – Contrast function that can be: - 1D array of length N (contrast values) - 2D array with total elements N (reshaped to 1D) - 2D diagonal matrix with shape (N, N) (diagonal extracted)

Returns:

Kernel matrix K with shape (N, N) representing the modified identity matrix (I - GD*X) for electromagnetic scattering

Return type:

numpy.ndarray

Notes

The kernel matrix is computed as: K[n, m] = -GD[n, m] * X[n] for n ≠ m K[n, n] = 1 - GD[n, n] * X[n]

This represents the discretized form of the Lippmann-Schwinger equation operator (I - GD*X) commonly used in electromagnetic inverse scattering.

Examples

>>> GD = np.random.complex128((4096, 4096))  # 64x64 grid
>>> X = np.random.complex128((4096,))        # 1D contrast
>>> K = kernel_GDX(GD, X)
>>> print(K.shape)  # (4096, 4096)
>>> # Verify identity structure
>>> I = np.eye(4096)
>>> expected = I - GD * X[:, np.newaxis]
>>> np.allclose(K, expected)  # Should be True
eispy2d.discretization.collocation.kernel_GSE(GS, E)#

Compute kernel matrix for scattered field Green’s function.

Computes the kernel matrix K for the scattered field using the Green’s function matrix GS and electric field E. This function is optimized for electromagnetic inverse scattering computations.

Parameters:
  • GS (numpy.ndarray) – Green’s function matrix for scattered field with shape (NM, N) where NM is the number of measurement points and N is the number of discretization elements

  • E (numpy.ndarray) – Electric field matrix with shape (N, NS) where N is the number of discretization elements and NS is the number of sources

Returns:

Kernel matrix K with shape (NM*NS, N) containing the computed kernel values for electromagnetic scattering

Return type:

numpy.ndarray

Notes

The kernel matrix is computed as: K[m*NS + s, n] = GS[m, n] * E[n, s]

This function uses Numba JIT compilation for improved performance in iterative electromagnetic reconstruction algorithms.

Examples

>>> GS = np.random.complex128((128, 64*64))  # 128 measurements, 64x64 grid
>>> E = np.random.complex128((64*64, 16))    # 64x64 grid, 16 sources
>>> K = kernel_GSE(GS, E)
>>> print(K.shape)  # (128*16, 64*64) = (2048, 4096)
eispy2d.discretization.collocation.kernel_GSX(GS, X)#

Compute kernel matrix for scattered field Green’s function with contrast.

Computes the kernel matrix for the scattered field using the Green’s function matrix GS and contrast function X. This function handles different input formats for the contrast function.

Parameters:
  • GS (numpy.ndarray) – Green’s function matrix for scattered field with shape (NM, N) where NM is the number of measurement points and N is the number of discretization elements.

  • X (numpy.ndarray) – Contrast function that can be: - 1D array of length N (contrast values) - 2D array with total elements N (reshaped to 1D) - 2D diagonal matrix with shape (N, N) (diagonal extracted)

Returns:

Kernel matrix K with shape (NM, N) containing the computed kernel values for electromagnetic scattering with contrast.

Return type:

numpy.ndarray

Notes

The kernel matrix is computed as:

\[K[m, n] = GS[m, n] \cdot X[n]\]

This function automatically handles different contrast formats: - Vector contrast: Direct multiplication - Matrix contrast: Diagonal elements used - Reshaped contrast: Automatically flattened

Examples

>>> GS = np.random.complex128((128, 64*64))  # 128 measurements, 64x64 grid
>>> X = np.random.complex128((64*64,))       # 1D contrast
>>> K = kernel_GSX(GS, X)
>>> print(K.shape)  # (128, 64*64) = (128, 4096)
>>> # Using 2D contrast matrix
>>> X_2d = np.random.complex128((64*64, 64*64))
>>> K = kernel_GSX(GS, X_2d)  # Uses diagonal elements
eispy2d.discretization.collocation.lhs_XEi(X, Ei)#

Compute left-hand side matrix for contrast and incident field.

Computes the left-hand side matrix by multiplying the contrast function X with the incident electric field Ei. This operation is commonly used in electromagnetic inverse scattering formulations for computing the source term in the Lippmann-Schwinger equation.

Parameters:
  • X (numpy.ndarray) – Contrast function with shape (N,) where N is the number of discretization elements.

  • Ei (numpy.ndarray) – Incident electric field matrix with shape (N, NS) where N is the number of discretization elements and NS is the number of sources.

Returns:

Left-hand side matrix with shape (N, NS) containing the element-wise product \(X \cdot Ei\) for each source.

Return type:

numpy.ndarray

Notes

The computation is performed as:

\[\text{lhs}[n, s] = X[n] \cdot Ei[n, s]\]

This represents the source term in the electromagnetic inverse scattering equation: \(X \cdot Ei\), where X is the contrast function and Ei is the incident field.

Examples

>>> X = np.random.complex128((4096,))      # 64x64 grid contrast
>>> Ei = np.random.complex128((4096, 16))  # 64x64 grid, 16 sources
>>> lhs = lhs_XEi(X, Ei)
>>> print(lhs.shape)  # (4096, 16)
>>> # Verify computation for first source
>>> expected = X * Ei[:, 0]
>>> np.allclose(lhs[:, 0], expected)  # Should be True

eispy2d.discretization.discretization module#

Discretization Abstract Base Class for Electromagnetic Inverse Scattering.

This module provides the abstract base class for spatial discretization methods used in electromagnetic inverse scattering problems. The Discretization class defines the interface that all discretization schemes must implement to work with the eispy2d library.

Discretization methods are responsible for: - Converting continuous electromagnetic fields to discrete representations - Defining spatial grids and basis functions - Computing residuals for data and state equations - Solving linear systems arising from discretization - Converting between different field representations - Interpolating solutions to different resolutions

The abstract nature of this class ensures that different discretization methods (such as method of moments, finite differences, finite elements, etc.) can be used interchangeably within the same inverse scattering algorithms.

Classes#

Discretization

Abstract base class for all discretization methods

Constants#

NAMEstr

Dictionary key for discretization name in saved data

ALIASstr

Dictionary key for discretization alias in saved data

CONFIGURATIONstr

Dictionary key for configuration object in saved data

Notes

This class is designed to be inherited by specific discretization implementations such as: - Method of Moments (MoM) - Finite Difference Methods - Finite Element Methods - Collocation Methods - Other spatial discretization schemes

All methods are abstract and must be implemented by derived classes to provide the specific mathematical operations required for each discretization approach.

Examples

This class is not intended to be used directly, but rather as a base for specific implementations:

>>> # Example of a derived class structure
>>> class MyDiscretization(Discretization):
...     def __init__(self, configuration, **kwargs):
...         super().__init__(configuration, name='My Discretization', **kwargs)
...         # Initialize discretization-specific parameters
...
...     def solve(self, scattered_field, **kwargs):
...         # Implement specific discretization method
...         return solution
...
...     # Implement other abstract methods...
class eispy2d.discretization.discretization.Discretization(configuration=None, name=None, alias='', import_filename=None, import_filepath='')#

Bases: ABC

Abstract base class for spatial discretization methods.

This class defines the interface that all discretization methods must implement for electromagnetic inverse scattering problems. It provides the foundation for converting continuous field problems into discrete algebraic systems that can be solved numerically.

The discretization handles the spatial aspect of the inverse scattering problem, defining how continuous electromagnetic fields are represented on discrete grids and how the governing equations are discretized.

Key responsibilities include: - Spatial grid generation and management - Field representation using basis functions - Residual computation for data and state equations - Linear system solution for field reconstruction - Resolution conversion and field interpolation - Green’s function matrix computation and storage

Parameters:
  • configuration (Configuration, optional) – Problem configuration object containing electromagnetic parameters, geometry definitions, and solver settings. If None, must be set before solving.

  • name (str, optional) – Human-readable name for the discretization method

  • alias (str, default='') – Short identifier for the discretization, used in file naming and method identification

  • import_filename (str, optional) – If provided, loads discretization state from this file

  • import_filepath (str, default='') – Directory path for import file

configuration#

Problem configuration object

Type:

Configuration

name#

Discretization method name

Type:

str

alias#

Method identifier string

Type:

str

residual_data(scattered_field, contrast=None, total_field=None, current=None)#

Compute residual for data equation

residual_state(incident_field, contrast=None, total_field=None, current=None)#

Compute residual for state equation

solve(scattered_field=None, incident_field=None, contrast=None, total_field=None, current=None, linear_solver=None)#

Solve linear system for field reconstruction

scattered_field(contrast=None, total_field=None, current=None)#

Compute scattered field from given parameters

contrast_image(coefficients, resolution)#

Convert coefficients to contrast image at given resolution

total_image(coefficients, resolution)#

Convert coefficients to total field image at given resolution

copy(new=None)#

Create copy of discretization instance

save(file_path='')#

Save discretization state to file

importdata(file_name, file_path='')#

Load discretization state from file

Notes

This is an abstract base class - all methods marked with @abstractmethod must be implemented by derived classes. The class provides parameter validation and error checking for the abstract methods.

Different discretization methods will implement these abstract methods according to their specific mathematical formulations: - Method of Moments uses basis functions and testing functions - Finite Differences use grid-based approximations - Finite Elements use element-based basis functions - Collocation uses point-wise matching

Examples

This class cannot be instantiated directly. Use derived classes:

>>> # Example derived class usage
>>> from collocation import Collocation
>>> discretization = Collocation(configuration, name='Pulse Collocation')
>>>
>>> # Solve linear inverse problem
>>> contrast = discretization.solve(
...     scattered_field=measured_data,
...     incident_field=incident_data,
...     linear_solver=regularization_method
... )
>>>
>>> # Convert to image format
>>> image = discretization.contrast_image(contrast, resolution)

See also

collocation.Collocation

Collocation method implementation

__init__(configuration=None, name=None, alias='', import_filename=None, import_filepath='')#

Initialize the discretization method.

Parameters:
  • configuration (Configuration, optional) – Problem configuration object containing electromagnetic parameters, geometry, frequency, and other problem-specific settings. If None, must be set before solving any problems.

  • name (str, optional) – Human-readable name for the discretization method. Used for identification and display purposes.

  • alias (str, default='') – Short identifier string for the discretization method. Used in file naming and method identification within algorithms.

  • import_filename (str, optional) – If provided, loads the discretization state from this file instead of initializing with the other parameters.

  • import_filepath (str, default='') – Directory path where the import file is located.

Notes

If import_filename is provided, the method loads its state from the specified file and ignores other initialization parameters. Otherwise, it initializes with the provided parameters.

The configuration object is copied to avoid unintended modifications to the original configuration during discretization operations.

Examples

>>> # Initialize with configuration
>>> config = Configuration(frequency=1e9, background_epsilon=1.0)
>>> discretization = MyDiscretization(
...     configuration=config,
...     name='My Method',
...     alias='mymeth'
... )
>>> # Initialize from saved state
>>> discretization = MyDiscretization(
...     import_filename='saved_state.pkl',
...     import_filepath='/path/to/files/'
... )
abstractmethod __str__()#

Return string representation of the discretization.

This method provides a string representation of the discretization method for display and debugging purposes. The base implementation provides a generic identifier.

Returns:

String representation of the discretization method

Return type:

str

Notes

Derived classes should override this method to provide more specific information about the discretization:

```python def __str__(self):

return f”{self.name}: {self.alias} - {self.configuration}”

```

Examples

>>> print(discretization)
Discretization: MyMethod - Config(freq=1GHz, nx=64, ny=64)
abstractmethod contrast_image(coefficients, resolution)#

Convert contrast coefficients to image format.

This method converts the discrete contrast function coefficients from the discretization basis to a regular image grid at the specified resolution. This is useful for visualization and analysis of reconstruction results.

Parameters:
  • coefficients (array_like) – Contrast function coefficients at discretization points, typically obtained from solving the inverse problem

  • resolution (array_like or tuple) – Desired image resolution as (nx, ny) where nx and ny are the number of pixels in x and y directions respectively

Returns:

2D array representing the contrast function image with shape matching the specified resolution

Return type:

array_like

Notes

The conversion process typically involves: 1. Interpolation from discretization points to image grid 2. Proper handling of boundary conditions 3. Scaling and normalization if needed

The image format allows for easy visualization and comparison with reference solutions or other reconstruction methods.

Examples

>>> # Convert to 64x64 image
>>> image = discretization.contrast_image(
...     coefficients=solution_coeffs,
...     resolution=(64, 64)
... )
>>>
>>> # Display the reconstruction
>>> import matplotlib.pyplot as plt
>>> plt.imshow(image.real, cmap='jet')
>>> plt.title('Reconstructed Contrast Function')
copy(new=None)#

Create a copy of the discretization instance.

This method creates a copy of the current discretization instance with the same configuration and settings. Since this is an abstract base class, the method cannot create a new instance directly.

Parameters:

new (Discretization, optional) – If provided, the current discretization’s configuration will be copied into this existing instance. If None, raises an error since abstract classes cannot be instantiated.

Returns:

This method only supports copying into an existing instance due to the abstract nature of the base class.

Return type:

None

Raises:

TypeError – If new is None, since abstract classes cannot be instantiated

Notes

This method is designed to be overridden by derived classes to provide proper copying functionality:

```python def copy(self, new=None):

if new is None:
return MyDiscretization(

configuration=self.configuration, name=self.name, alias=self.alias

)

else:

new.name = self.name new.configuration = self.configuration new.alias = self.alias

```

Examples

>>> # Copy into existing instance (derived class)
>>> target = MyDiscretization()
>>> source.copy(target)
>>> print(target.name)  # Same as source.name
abstractmethod importdata(file_name, file_path='')#

Load discretization state from file.

This method loads discretization configuration and state from a previously saved file. The base implementation handles common parameters, but derived classes should extend this to restore method-specific data.

Parameters:
  • file_name (str) – Name of the file containing the saved discretization state

  • file_path (str, default='') – Directory path where the save file is located

Returns:

Dictionary containing the loaded discretization state data

Return type:

dict

Notes

Derived classes should override this method to restore additional method-specific data:

```python def importdata(self, file_name, file_path=’’):

data = super().importdata(file_name, file_path=file_path) self.my_specific_param = data[‘my_specific_param’] return data

```

The method completely replaces the current discretization state with the loaded configuration.

Examples

>>> # Load discretization state
>>> data = discretization.importdata(
...     file_name='discretization_state.pkl',
...     file_path='/path/to/files/'
... )
>>> print(f"Loaded discretization: {discretization.name}")
Raises:
  • FileNotFoundError – If the specified file does not exist

  • KeyError – If required keys are missing from the saved data

abstractmethod residual_data(scattered_field, contrast=None, total_field=None, current=None)#

Compute residual for the data equation.

This method computes the residual (error) between measured scattered field data and the scattered field predicted by the current estimate of the scatterer properties. The residual is used in optimization algorithms to minimize the data misfit.

The data equation relates the scattered field to the scatterer properties and internal fields:

\[E^s = G^s J\]

where \(E^s\) is the scattered field, \(G^s\) is the scattered field Green’s function, and \(J\) is the contrast source.

Parameters:
  • scattered_field (array_like) – Measured scattered field data at receiver locations.

  • contrast (array_like, optional) – Contrast function values at discretization points. Required if total_field is provided.

  • total_field (array_like, optional) – Total electric field at discretization points. Required if contrast is provided.

  • current (array_like, optional) – Contrast source (current) at discretization points. If provided, contrast and total_field are ignored.

Returns:

Data residual vector representing the difference between measured and computed scattered field.

Return type:

array_like

Raises:
  • MissingInputError – If required parameter combinations are not provided.

  • Error – If no valid parameter combination is given.

Notes

The method requires either: - Both contrast and total_field parameters, or - The current parameter alone.

The residual is computed as: residual = measured_scattered_field - predicted_scattered_field

A small residual indicates good agreement between the model and data.

Examples

>>> # Using contrast and total field
>>> residual = discretization.residual_data(
...     scattered_field=measured_data,
...     contrast=current_contrast,
...     total_field=current_total_field
... )
>>> # Using current directly
>>> residual = discretization.residual_data(
...     scattered_field=measured_data,
...     current=current_source
... )
abstractmethod residual_state(incident_field, contrast=None, total_field=None, current=None)#

Compute residual for the state equation.

This method computes the residual (error) in the state equation, which relates the total field, contrast function, and current source. The state equation ensures consistency between the electromagnetic field quantities within the scattering domain.

The state equation can be written as:

\[J = \chi E^t\]

where \(J\) is the contrast source, \(\chi\) is the contrast function, and \(E^t\) is the total electric field.

Parameters:
  • incident_field (array_like) – Incident electric field at discretization points.

  • contrast (array_like, optional) – Contrast function values at discretization points. Required if total_field or current is provided.

  • total_field (array_like, optional) – Total electric field at discretization points. Used with contrast to compute current source.

  • current (array_like, optional) – Contrast source (current) at discretization points. Used with contrast to validate state equation.

Returns:

State residual vector representing the inconsistency in the state equation.

Return type:

array_like

Raises:
  • MissingInputError – If required parameter combinations are not provided.

  • Error – If no valid parameter combination is given.

Notes

The method requires: - contrast parameter along with either total_field or current.

The residual measures how well the state equation is satisfied: - If using total_field: residual = contrast * total_field - current - If using current: residual = contrast * (incident + scattered) - current

A small residual indicates good consistency between field quantities.

Examples

>>> # Using contrast and total field
>>> residual = discretization.residual_state(
...     incident_field=incident_data,
...     contrast=current_contrast,
...     total_field=current_total_field
... )
>>> # Using contrast and current
>>> residual = discretization.residual_state(
...     incident_field=incident_data,
...     contrast=current_contrast,
...     current=current_source
... )
abstractmethod save(file_path='')#

Save discretization state to file.

This method saves the discretization configuration and state to a file for later restoration. The base implementation provides the common data structure, but derived classes should extend this to include method-specific parameters.

Parameters:

file_path (str, default='') – Base path for saving the discretization state. The specific filename will be determined by the derived class implementation.

Returns:

Dictionary containing the discretization state data including: - name: Discretization method name - alias: Method identifier - configuration: Problem configuration object

Return type:

dict

Notes

Derived classes should override this method to include additional method-specific data:

```python def save(self, file_path=’’):

data = super().save(file_path=file_path) data[‘my_specific_param’] = self.my_specific_param # Save to file using file_path return data

```

The returned dictionary contains all necessary information to restore the discretization state using importdata.

Examples

>>> # Save discretization state
>>> data = discretization.save(file_path='/path/to/save/')
>>> print(f"Saved {len(data)} parameters")
abstractmethod scattered_field(contrast=None, total_field=None, current=None)#

Compute scattered field from scatterer properties.

This method computes the scattered electric field at receiver locations given the scatterer properties (contrast function, total field, or current source). This is the forward scattering operation.

The scattered field is computed using: .. math:

E^s = G^s J

where \(G^s\) is the scattered field Green’s function matrix and \(J\) is the contrast source.

Parameters:
  • contrast (array_like, optional) – Contrast function values at discretization points. Required if total_field is provided.

  • total_field (array_like, optional) – Total electric field at discretization points. Required if contrast is provided.

  • current (array_like, optional) – Contrast source (current) at discretization points. Alternative to providing contrast and total_field separately.

Returns:

Scattered electric field at receiver locations

Return type:

array_like

Raises:

MissingInputError – If required parameter combinations are not provided

Notes

The method requires either: - Both contrast and total_field parameters, or - The current parameter alone

If contrast and total_field are provided, the current source is computed as J = chi E^t, then used to calculate the scattered field.

Examples

>>> # Using contrast and total field
>>> scattered = discretization.scattered_field(
...     contrast=contrast_values,
...     total_field=total_field_values
... )
>>> # Using current directly
>>> scattered = discretization.scattered_field(
...     current=current_source
... )
abstractmethod solve(scattered_field=None, incident_field=None, contrast=None, total_field=None, current=None, linear_solver=None)#

Solve the linear inverse scattering problem.

This method solves the discretized linear inverse scattering problem to reconstruct the contrast function from measured scattered field data. The solution involves solving a linear system that may be ill-conditioned, requiring regularization techniques.

The linear problem typically has the form:

\[G \chi = E^s\]

where \(G\) is the system matrix, \(\chi\) is the contrast function to be reconstructed, and \(E^s\) is the scattered field data.

Parameters:
  • scattered_field (array_like, optional) – Measured scattered field data at receiver locations.

  • incident_field (array_like, optional) – Incident electric field at discretization points.

  • contrast (array_like, optional) – Initial or known contrast function values.

  • total_field (array_like, optional) – Total electric field at discretization points.

  • current (array_like, optional) – Contrast source (current) at discretization points.

  • linear_solver (Regularization, optional) – Regularization/linear solver method to use for solving the potentially ill-conditioned linear system.

Returns:

Reconstructed contrast function coefficients at discretization points.

Return type:

array_like

Notes

The specific parameters required depend on the discretization method and the formulation of the linear system. Common approaches include: - Born approximation: uses incident field as total field - Moment method: requires Green’s function matrices - Finite differences: uses grid-based operators

The linear solver handles regularization to deal with ill-conditioning that is common in inverse scattering problems.

Examples

>>> # Basic Born approximation solution
>>> contrast = discretization.solve(
...     scattered_field=measured_data,
...     incident_field=incident_data,
...     linear_solver=tikhonov_solver
... )
>>> # Advanced solution with known total field
>>> contrast = discretization.solve(
...     scattered_field=measured_data,
...     total_field=computed_total_field,
...     linear_solver=truncated_svd_solver
... )
abstractmethod total_image(coefficients, resolution)#

Convert total field coefficients to image format.

This method converts the discrete total field coefficients from the discretization basis to a regular image grid at the specified resolution. This is useful for visualization and analysis of field distributions.

Parameters:
  • coefficients (array_like) – Total field coefficients at discretization points, typically obtained from solving the forward problem

  • resolution (array_like or tuple) – Desired image resolution as (nx, ny) where nx and ny are the number of pixels in x and y directions respectively

Returns:

2D array representing the total field image with shape matching the specified resolution

Return type:

array_like

Notes

The conversion process typically involves: 1. Interpolation from discretization points to image grid 2. Proper handling of boundary conditions 3. Phase and amplitude representation 4. Scaling and normalization if needed

The image format allows for visualization of field patterns and understanding of scattering behavior.

Examples

>>> # Convert to 128x128 image
>>> field_image = discretization.total_image(
...     coefficients=field_coeffs,
...     resolution=(128, 128)
... )
>>>
>>> # Display field magnitude
>>> import matplotlib.pyplot as plt
>>> plt.imshow(np.abs(field_image), cmap='viridis')
>>> plt.title('Total Field Magnitude')

eispy2d.discretization.richmond module#

class eispy2d.discretization.richmond.Richmond(configuration=None, elements=None, state=True, alias='ric', import_filename=None, import_filepath='')#

Bases: Collocation

Richmond discretization method for electromagnetic inverse scattering.

Implements the Richmond discretization method, which is a specific case of the collocation method using pulse basis functions. This method is widely used in electromagnetic inverse scattering for its simplicity and numerical stability, particularly when dealing with the singularities in the Green’s function integrals.

The Richmond method approximates the scattered field using: - Pulse basis functions for the contrast function - Collocation points at the center of each discretization cell - Analytical treatment of the Green’s function singularity

Parameters:
  • configuration (Configuration) – Problem configuration object.

  • elements (int or tuple of int) – Number of discretization elements. If int, creates square grid (N×N). If tuple, creates rectangular grid (NY×NX).

  • state (bool, default: True) – If True, computes the state-space Green’s function matrix (GD).

  • alias (str, default: 'ric') – Short alias for the method.

  • import_filename (str, optional) – Filename to import configuration from.

  • import_filepath (str, default='') – Path to import file.

GS#

Data-space Green’s function matrix (measurements × elements).

Type:

numpy.ndarray

GD#

State-space Green’s function matrix (elements × elements). None if state=False at initialization.

Type:

numpy.ndarray or None

residual_data()#

Compute residual for the data equation.

residual_state()#

Compute residual for the state equation.

solve()#

Solve linear inverse scattering problem.

scattered_field()#

Compute scattered field from scatterer properties.

contrast_image()#

Convert contrast coefficients to image format.

total_image()#

Convert total field coefficients to image format.

Notes

The Green’s function matrices are computed using the analytical formulas from Richmond’s method, which handles the singularity at the origin by using the small-argument approximation of the Hankel function.

Examples

>>> config = Configuration(name='test', wavelength=1.0)
>>> discretization = Richmond(configuration=config, elements=(32, 32))
>>>
>>> # Access Green's function matrices
>>> print(f"GS shape: {discretization.GS.shape}")
>>> print(f"GD shape: {discretization.GD.shape}")
contrast_image(coefficients, resolution)#

Convert contrast coefficients to image format.

This method converts the discrete contrast function coefficients from the discretization basis to a regular image grid at the specified resolution. This is useful for visualization and analysis of reconstruction results.

Parameters:
  • coefficients (array_like) – Contrast function coefficients at discretization points, typically obtained from solving the inverse problem

  • resolution (array_like or tuple) – Desired image resolution as (nx, ny) where nx and ny are the number of pixels in x and y directions respectively

Returns:

2D array representing the contrast function image with shape matching the specified resolution

Return type:

array_like

Notes

The conversion process typically involves: 1. Interpolation from discretization points to image grid 2. Proper handling of boundary conditions 3. Scaling and normalization if needed

The image format allows for easy visualization and comparison with reference solutions or other reconstruction methods.

Examples

>>> # Convert to 64x64 image
>>> image = discretization.contrast_image(
...     coefficients=solution_coeffs,
...     resolution=(64, 64)
... )
>>>
>>> # Display the reconstruction
>>> import matplotlib.pyplot as plt
>>> plt.imshow(image.real, cmap='jet')
>>> plt.title('Reconstructed Contrast Function')
copy(new=None)#

Create a copy of the collocation instance.

Creates either a new independent instance or copies the configuration to an existing instance.

Parameters:

new (Collocation or None, default=None) – If None, creates a new independent instance If provided, copies configuration to this instance

Returns:

New instance if new=None, otherwise None

Return type:

Collocation or None

Examples

>>> # Create independent copy
>>> collocation_copy = collocation.copy()
>>> # Copy configuration to existing instance
>>> new_collocation = Collocation(configuration=config,
...                              trial='pulse',
...                              elements=(32, 32))
>>> collocation.copy(new_collocation)
importdata(file_name, file_path='')#

Import collocation configuration from a saved file.

Loads a previously saved collocation configuration including trial function type and discretization elements.

Parameters:
  • file_name (str) – Name of the file to import from

  • file_path (str, default='') – Path to the file location

Examples

>>> collocation = Collocation()
>>> collocation.importdata('collocation_config.pkl', '/path/to/files/')
residual_data(scattered_field, contrast=None, total_field=None, current=None)#

Compute residual for the data equation using Richmond discretization.

Parameters

contrastarray_like, optional

Contrast function values.

total_fieldarray_like, optional

Total electric field.

currentarray_like, optional

Contrast source (current).

Returns:

Residual vector: \(E^s - G^s J\) where \(J\) is either \(\chi E^t\) or the provided current.

Return type:

array_like

Notes

The residual is computed as: - If current is None: \(\text{res} = E^s - G^s \chi E^t\) - If current is provided: \(\text{res} = E^s - G^s J\)

residual_state(incident_field, contrast=None, total_field=None, current=None)#

Compute residual for the state equation using Richmond discretization.

Parameters:
  • incident_field (array_like) – Incident electric field.

  • contrast (array_like, optional) – Contrast function values.

  • total_field (array_like, optional) – Total electric field.

  • current (array_like, optional) – Contrast source (current).

Returns:

Residual vector.

Return type:

array_like

Notes

The residual depends on the parameters provided: - If current is None: \(\text{res} = E^t - E^i - G^D \chi E^t\) - If current is provided: \(\text{res} = J - \chi E^i - \chi G^D J\)

save(file_path='')#

Save the collocation configuration to a file.

Saves the complete collocation method configuration including trial function type and discretization elements using pickle serialization.

Parameters:

file_path (str, default='') – Path where the configuration file will be saved

Examples

>>> collocation.save('/path/to/save/')
>>> collocation.save()  # Save in current directory
scattered_field(contrast=None, total_field=None, current=None)#

Compute scattered field from scatterer properties.

This method computes the scattered electric field at receiver locations given the scatterer properties (contrast function, total field, or current source). This is the forward scattering operation.

The scattered field is computed using: .. math:

E^s = G^s J

where \(G^s\) is the scattered field Green’s function matrix and \(J\) is the contrast source.

Parameters:
  • contrast (array_like, optional) – Contrast function values at discretization points. Required if total_field is provided.

  • total_field (array_like, optional) – Total electric field at discretization points. Required if contrast is provided.

  • current (array_like, optional) – Contrast source (current) at discretization points. Alternative to providing contrast and total_field separately.

Returns:

Scattered electric field at receiver locations

Return type:

array_like

Raises:

MissingInputError – If required parameter combinations are not provided

Notes

The method requires either: - Both contrast and total_field parameters, or - The current parameter alone

If contrast and total_field are provided, the current source is computed as J = chi E^t, then used to calculate the scattered field.

Examples

>>> # Using contrast and total field
>>> scattered = discretization.scattered_field(
...     contrast=contrast_values,
...     total_field=total_field_values
... )
>>> # Using current directly
>>> scattered = discretization.scattered_field(
...     current=current_source
... )
solve(scattered_field=None, incident_field=None, contrast=None, total_field=None, current=None, linear_solver=None)#

Solve the linear inverse scattering problem using Richmond discretization.

Parameters:
  • scattered_field (array_like, optional) – Measured scattered field data.

  • incident_field (array_like, optional) – Incident electric field.

  • contrast (array_like, optional) – Contrast function values.

  • total_field (array_like, optional) – Total electric field.

  • current (array_like, optional) – Contrast source.

  • linear_solver (Regularization, optional) – Regularization method for solving the linear system.

Returns:

Reconstructed contrast function or field coefficients.

Return type:

array_like

Notes

The method can solve for: - Contrast function X: requires scattered_field and total_field - Total field E: requires scattered_field and contrast - Current source J: requires scattered_field - Other combinations for state-space problems.

total_image(coefficients, resolution)#

Convert total field coefficients to image format.

This method converts the discrete total field coefficients from the discretization basis to a regular image grid at the specified resolution. This is useful for visualization and analysis of field distributions.

Parameters:
  • coefficients (array_like) – Total field coefficients at discretization points, typically obtained from solving the forward problem

  • resolution (array_like or tuple) – Desired image resolution as (nx, ny) where nx and ny are the number of pixels in x and y directions respectively

Returns:

2D array representing the total field image with shape matching the specified resolution

Return type:

array_like

Notes

The conversion process typically involves: 1. Interpolation from discretization points to image grid 2. Proper handling of boundary conditions 3. Phase and amplitude representation 4. Scaling and normalization if needed

The image format allows for visualization of field patterns and understanding of scattering behavior.

Examples

>>> # Convert to 128x128 image
>>> field_image = discretization.total_image(
...     coefficients=field_coeffs,
...     resolution=(128, 128)
... )
>>>
>>> # Display field magnitude
>>> import matplotlib.pyplot as plt
>>> plt.imshow(np.abs(field_image), cmap='viridis')
>>> plt.title('Total Field Magnitude')
eispy2d.discretization.richmond.richmond_data(configuration, elements)#
eispy2d.discretization.richmond.richmond_state(configuration, elements)#

Module contents#