Loading...
Loading...
Linear operators for large-scale inverse problems with matrix-free representations. Use when Claude needs to: (1) Define linear operators for forward/adjoint operations, (2) Solve inverse problems (deconvolution, imaging, tomography), (3) Apply signal processing transforms (FFT, convolution, derivatives), (4) Compose operators for complex workflows, (5) Perform regularized inversion with smoothness or sparsity constraints, (6) Process seismic or image data at scale.
npx skill4agent add steadfastasart/geoscience-skills pylopsimport numpy as np
import pylops
# Create operator and apply forward/adjoint
A = pylops.FirstDerivative(n=100, dtype='float64')
y = A @ x # Forward: y = A @ x
x_adj = A.H @ y # Adjoint: x = A.H @ y
x_est = A / y # Solve inverse problem| Class | Purpose |
|---|---|
| Base class for all operators |
| Vertical/horizontal operator stacking |
| Block diagonal operator composition |
# Diagonal operator
D = pylops.Diagonal(np.array([1., 2., 3.]))
y = D @ x; x_adj = D.H @ y
# Derivatives
D1 = pylops.FirstDerivative(n, dtype='float64')
D2 = pylops.SecondDerivative(n, dtype='float64')
G = pylops.Gradient(dims=(64, 64), dtype='float64')wavelet = np.sin(np.linspace(0, 2*np.pi, 21)) * np.hanning(21)
C = pylops.signalprocessing.Convolve1D(n, h=wavelet, offset=10)
y = C @ x # Convolve
x_adj = C.H @ y # Correlation (adjoint)# Chain: y = C @ B @ A @ x
composed = pylops.Smoothing1D(5, n) @ pylops.FirstDerivative(n) @ pylops.Identity(n)
# Stack operators
V = pylops.VStack([A, B]) # Vertical: (2n, n)
H = pylops.HStack([A, B]) # Horizontal: (n, 2n)
BD = pylops.BlockDiag([A, B]) # Block diagonal: (2n, 2n)# Simple least squares
x_est = A / y
# Normal equations
x_est = pylops.optimization.leastsquares.NormalEquationsInversion(A, None, y)
# Regularized inversion with smoothness
Reg = pylops.SecondDerivative(n)
x_est = pylops.optimization.leastsquares.RegularizedInversion(
A, [Reg], y, epsRs=[0.1]
)x_lsqr = pylops.optimization.solver.lsqr(A, y, iter_lim=100)[0]
x_cgls = pylops.optimization.solver.cgls(A, y, niter=100)[0]x_l1 = pylops.optimization.sparsity.fista(A, y, niter=100, eps=0.1)[0]A = pylops.FirstDerivative(100)
pylops.utils.dottest(A, 100, 100, verb=True) # Dot test passed!C = pylops.signalprocessing.Convolve1D(n, h=wavelet, offset=len(wavelet)//2)
seismic = C @ reflectivity
# Deconvolve (regularized)
Reg = pylops.SecondDerivative(n)
reflectivity_est = pylops.optimization.leastsquares.RegularizedInversion(
C, [Reg], seismic, epsRs=[0.01]
)ny, nx = image.shape
G = pylops.Gradient(dims=(ny, nx))
x_tv = pylops.optimization.sparsity.splitbregman(
pylops.Identity(ny*nx), G, image.ravel(),
niter_inner=5, niter_outer=10, mu=1.0, epsRL1s=[0.1]
)[0].reshape(ny, nx)| Scenario | Recommendation |
|---|---|
| Matrix-free linear operators for large inverse problems | PyLops - purpose-built, memory efficient |
| Sparse matrix operations with known structure | scipy.sparse - standard, well-documented |
| Simple convolution/deconvolution | PyLops - clean API with |
| Custom operators for small problems | Custom NumPy/SciPy - no extra dependency |
| GPU-accelerated linear algebra | PyLops - pass CuPy arrays for automatic GPU |
| Seismic deconvolution or imaging operators | PyLops - rich signal processing operator library |
@VStackBlockDiagConvolve1Dpylops.utils.dottest()SecondDerivativeRegularizedInversion(C, [Reg], data, epsRs=[eps])epsRspylops.optimization.sparsity.fista().matvec().rmatvec().shapepylops.utils.dottest()