Example #1
0
plt.colorbar(im, ax=axs[0])
im = axs[1].imshow(B, interpolation='nearest', cmap='rainbow')
axs[1].axis('tight')
axs[1].set_title('y')
plt.colorbar(im, ax=axs[1])
plt.tight_layout()
plt.subplots_adjust(top=0.8)


###############################################################################
# We use the symmetrical Laplacian operator as well
# as a asymmetrical version of it (by adding more weight to the
# derivative along one direction)

# symmetrical
L2symop = pylops.Laplacian(dims=(nx, ny), weights=(1, 1), dtype='float64')

# asymmetrical
L2asymop = pylops.Laplacian(dims=(nx, ny), weights=(3, 1), dtype='float64')

Bsym = np.reshape(L2symop * A.flatten(), (nx, ny))
Basym = np.reshape(L2asymop * A.flatten(), (nx, ny))

fig, axs = plt.subplots(1, 3, figsize=(10, 3))
fig.suptitle('Laplacian', fontsize=12,
             fontweight='bold', y=0.95)
im = axs[0].imshow(A, interpolation='nearest', cmap='rainbow')
axs[0].axis('tight')
axs[0].set_title('x')
plt.colorbar(im, ax=axs[0])
im = axs[1].imshow(Bsym, interpolation='nearest', cmap='rainbow')
# We can now define a set of available samples in the
# first and second direction of the array and apply bilinear interpolation.
nsamples = 2000
iava = np.vstack(
    (np.random.uniform(0, nz - 1,
                       nsamples), np.random.uniform(0, nx - 1, nsamples)))

Bop = pylops.signalprocessing.Bilinear(iava, (nz, nx))
y = Bop * x.ravel()

###############################################################################
# At this point we try to reconstruct the input signal imposing a smooth
# solution by means of a regularization term that minimizes the Laplacian of
# the solution.

D2op = pylops.Laplacian((nz, nx), weights=(1, 1), dtype='float64')

xadj = Bop.H * y
xinv = pylops.optimization.leastsquares.NormalEquationsInversion(
    Bop, [D2op],
    y,
    epsRs=[np.sqrt(0.1)],
    returninfo=False,
    **dict(maxiter=100))
xadj = xadj.reshape(nz, nx)
xinv = xinv.reshape(nz, nx)

fig, axs = plt.subplots(1, 3, figsize=(10, 4))
fig.suptitle('Bilinear interpolation', fontsize=14, fontweight='bold', y=0.95)
axs[0].imshow(x, cmap='gray_r', vmin=0, vmax=250)
axs[0].axis('tight')
                               dims=(nt, nx),
                               sampling=dt,
                               dir=0,
                               halfcurrent=True)

y = Cop * x.flatten()
y = y.reshape(nt, nx)
yn = y + np.random.normal(0, 4e-1, y.shape)

# Numerical derivative
Dop = pylops.FirstDerivative(nt * nx, dims=(nt, nx), dir=0, sampling=dt)
xder = Dop * yn.flatten()
xder = xder.reshape(nt, nx)

# Regularized derivative
Rop = pylops.Laplacian(dims=(nt, nx))
xreg = pylops.RegularizedInversion(Cop, [Rop],
                                   yn.flatten(),
                                   epsRs=[1e0],
                                   **dict(iter_lim=100, atol=1e-5))
xreg = xreg.reshape(nt, nx)

# Preconditioned derivative
Sop = pylops.Smoothing2D((11, 21), dims=(nt, nx))
xp = pylops.PreconditionedInversion(Cop, Sop, yn.flatten(),
                                    **dict(iter_lim=10, atol=1e-2))
xp = xp.reshape(nt, nx)

# Visualize data and inversion
vmax = 2 * np.max(np.abs(x))
fig, axs = plt.subplots(2, 3, figsize=(18, 12))
Example #4
0
# To start we import a 2d image and define our restriction operator to irregularly and randomly
# sample the image for 30% of the entire grid
im = np.load("../testdata/python.npy")[:, :, 0]

Nz, Nx = im.shape
N = Nz * Nx

# Subsample signal
perc_subsampling = 0.2

Nsub2d = int(np.round(N * perc_subsampling))
iava = np.sort(np.random.permutation(np.arange(N))[:Nsub2d])

# Create operators and data
Rop = pylops.Restriction(N, iava, dtype="float64")
D2op = pylops.Laplacian((Nz, Nx), weights=(1, 1), dtype="float64")

x = im.ravel()
y = Rop * x
y1 = Rop.mask(x)

###############################################################################
# We will now use two different routines from our optimization toolbox
# to estimate our original image in the regular grid.

xcg_reg_lop = pylops.optimization.leastsquares.NormalEquationsInversion(
    Rop, [D2op],
    y,
    epsRs=[np.sqrt(0.1)],
    returninfo=False,
    **dict(maxiter=200))
Example #5
0
###############################################################################
# Finally we take advantage of our different solvers and try to invert the
# modelling operator both in a least-squares sense and using TV-reg.
Dop = [
    pylops.FirstDerivative(ny * nx,
                           dims=(nx, ny),
                           dir=0,
                           edge=True,
                           dtype=np.float),
    pylops.FirstDerivative(ny * nx,
                           dims=(nx, ny),
                           dir=1,
                           edge=True,
                           dtype=np.float)
]
D2op = pylops.Laplacian(dims=(nx, ny), edge=True, dtype=np.float)

# L2
xinv_sm = \
    pylops.optimization.leastsquares.RegularizedInversion(RLop.H,
                                                          [D2op],
                                                          y.T.flatten(),
                                                          epsRs=[1e1],
                                                          **dict(iter_lim=20))
xinv_sm = np.real(xinv_sm.reshape(nx, ny)).T

# TV
mu = 1.5
lamda = [1., 1.]
niter = 3
niterinner = 4
Example #6
0
def Laplacian(shape: tuple, weights: Tuple[float] = (1, 1), step: Union[tuple, float] = 1., edge: bool = True,
              dtype: str = 'float64') -> PyLopLinearOperator:
    r"""
    Laplacian.

    Computes the Laplacian of a 2D array.


    Parameters
    ----------
    shape: tuple
        Shape of the input array.
    weights: Tuple[float]
        Weight to apply to each direction (real laplacian operator if ``weights=[1,1]``)
    step: Union[float, Tuple[float, ...]]
        Step size in each direction.
    edge: bool
       Use reduced order derivative at edges (``True``) or ignore them (``False``).
    dtype: str
        Type of elements in input vector.
    kind: str
        Derivative kind (``forward``, ``centered``, or ``backward``).

    Returns
    -------
    :py:class:`pycsou.core.linop.LinearOperator`
        Laplacian operator.

    Examples
    --------

    .. plot::

       import numpy as np
       import matplotlib.pyplot as plt
       from pycsou.linop.diff import Laplacian
       from pycsou.util.misc import peaks

       x  = np.linspace(-2.5, 2.5, 25)
       X,Y = np.meshgrid(x,x)
       Z = peaks(X, Y)
       Dop = Laplacian(shape=Z.shape)
       y = Dop * Z.flatten()

       plt.figure()
       h = plt.pcolormesh(X,Y,Z, shading='auto')
       plt.colorbar(h)
       plt.title('Signal')
       plt.figure()
       h = plt.pcolormesh(X,Y,y.reshape(X.shape), shading='auto')
       plt.colorbar(h)
       plt.title('Laplacian')
       plt.show()


    Notes
    -----
    The Laplacian operator sums the second directional derivatives of a 2D array along the two canonical directions.

    It is defined as:

    .. math::
        y[i, j] =\frac{x[i+1, j] + x[i-1, j] + x[i, j-1] +x[i, j+1] - 4x[i, j]}
                  {dx\times dy}.

    See Also
    --------
    :py:func:`~pycsou.linop.diff.DirectionalLaplacian`, :py:func:`~pycsou.linop.diff.SecondDerivative`

    """
    if isinstance(step, Number):
        step = [step] * len(shape)
    return PyLopLinearOperator(pylops.Laplacian(dims=shape, weights=weights, sampling=step, edge=edge, dtype=dtype))