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:
DiscretizationCollocation 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:
ABCAbstract 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:
- 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.CollocationCollocation 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:
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:
CollocationRichmond 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)#