.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "gallery/0300_cvx/partial_wh_sensor_cosine_basis.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_gallery_0300_cvx_partial_wh_sensor_cosine_basis.py: Random Orthogonal Measurements, Cosine Basis, ADMM ============================================================================== This example has following features: * The signal being measured is not sparse by itself. * It does have a sparse representation in discrete cosine basis. * Measurements are taken by a partial Walsh Hadamard sensing matrix with small number of orthonormal rows * The number of measurements is 8 times lower than the dimension of the signal space. * ADMM based Basis pursuit denoising is being used to solve the recovery problem. This example is adapted from YALL1 package. .. GENERATED FROM PYTHON SOURCE LINES 20-21 Let's import necessary libraries .. GENERATED FROM PYTHON SOURCE LINES 21-31 .. code-block:: default import jax.numpy as jnp from jax import random norm = jnp.linalg.norm import matplotlib as mpl import matplotlib.pyplot as plt from cr.sparse import lop from cr.sparse.cvx.adm import yall1 .. GENERATED FROM PYTHON SOURCE LINES 32-34 Setup ------ .. GENERATED FROM PYTHON SOURCE LINES 34-44 .. code-block:: default # Number of measurements m = 1024 # Ambient dimension n = m*8 key = random.PRNGKey(0) keys = random.split(key, 4) .. GENERATED FROM PYTHON SOURCE LINES 45-47 Non-sparse signal -------------------------- .. GENERATED FROM PYTHON SOURCE LINES 47-51 .. code-block:: default xs = 100 * jnp.cumsum(random.normal(keys[0], (n,))) plt.figure(figsize=(8,6), dpi= 100, facecolor='w', edgecolor='k') plt.plot(xs) .. image-sg:: /gallery/0300_cvx/images/sphx_glr_partial_wh_sensor_cosine_basis_001.png :alt: partial wh sensor cosine basis :srcset: /gallery/0300_cvx/images/sphx_glr_partial_wh_sensor_cosine_basis_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none [] .. GENERATED FROM PYTHON SOURCE LINES 52-54 The Sparsifying Basis -------------------------- .. GENERATED FROM PYTHON SOURCE LINES 54-61 .. code-block:: default Psi = lop.jit(lop.cosine_basis(n)) alpha = Psi.trans(xs) plt.figure(figsize=(8,6), dpi= 100, facecolor='w', edgecolor='k') plt.plot(alpha) .. image-sg:: /gallery/0300_cvx/images/sphx_glr_partial_wh_sensor_cosine_basis_002.png :alt: partial wh sensor cosine basis :srcset: /gallery/0300_cvx/images/sphx_glr_partial_wh_sensor_cosine_basis_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none [] .. GENERATED FROM PYTHON SOURCE LINES 62-64 Partial Walsh Hadamard Measurements Operator ------------------------------------------------ .. GENERATED FROM PYTHON SOURCE LINES 64-83 .. code-block:: default # indices of the measurements to be picked p = random.permutation(keys[1], n) picks = jnp.sort(p[:m]) # Make sure that DC component is always picked up picks = picks.at[0].set(0) print(f"{picks=}") # a random permutation of input perm = random.permutation(keys[2], n) print(f"{perm=}") # Walsh Hadamard Basis operator Twh = lop.walsh_hadamard_basis(n) # Wrap it with picks and perm Tpwh = lop.jit(lop.partial_op(Twh, picks, perm)) .. rst-class:: sphx-glr-script-out .. code-block:: none picks=Array([ 0, 16, 17, ..., 8181, 8189, 8191], dtype=int64) perm=Array([ 492, 5891, 6660, ..., 1416, 2648, 5917], dtype=int64) .. GENERATED FROM PYTHON SOURCE LINES 84-86 Measurement process ------------------------------------------------ .. GENERATED FROM PYTHON SOURCE LINES 86-98 .. code-block:: default # Perform exact measurement bs = Tpwh.times(xs) # Add some noise sigma = 0.2 noise = sigma * random.normal(keys[3], (m,)) b = bs + noise plt.figure(figsize=(8,6), dpi= 100, facecolor='w', edgecolor='k') plt.plot(b) .. image-sg:: /gallery/0300_cvx/images/sphx_glr_partial_wh_sensor_cosine_basis_003.png :alt: partial wh sensor cosine basis :srcset: /gallery/0300_cvx/images/sphx_glr_partial_wh_sensor_cosine_basis_003.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none [] .. GENERATED FROM PYTHON SOURCE LINES 99-101 Recovery using ADMM ------------------------------------------------ .. GENERATED FROM PYTHON SOURCE LINES 101-115 .. code-block:: default # tolerance for solution convergence tol = 5e-4 # BPDN parameter rho = 5e-4 # Run the solver sol = yall1.solve(Tpwh, b, rho=rho, tolerance=tol, W=Psi) iterations = int(sol.iterations) #Number of iterations print(f'{iterations=}') # Relative error rel_error = norm(sol.x-xs)/norm(xs) print(f'{rel_error=:.4e}') .. rst-class:: sphx-glr-script-out .. code-block:: none iterations=192 rel_error=7.8711e-02 .. GENERATED FROM PYTHON SOURCE LINES 116-118 Solution ------------------------------------------------ .. GENERATED FROM PYTHON SOURCE LINES 118-123 .. code-block:: default plt.figure(figsize=(8,6), dpi= 100, facecolor='w', edgecolor='k') plt.plot(xs, label='original') plt.plot(sol.x, label='recovered') plt.legend() .. image-sg:: /gallery/0300_cvx/images/sphx_glr_partial_wh_sensor_cosine_basis_004.png :alt: partial wh sensor cosine basis :srcset: /gallery/0300_cvx/images/sphx_glr_partial_wh_sensor_cosine_basis_004.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 4.425 seconds) .. _sphx_glr_download_gallery_0300_cvx_partial_wh_sensor_cosine_basis.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: partial_wh_sensor_cosine_basis.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: partial_wh_sensor_cosine_basis.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_