diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8989f3059..cd8009518 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,32 @@
Changelog
=========
+# 2.5.0
+* Added `cuda` engine to `pylops.waveeqprocessing.Kirchhoff`
+ operator
+* Added `Opbasis` and `optimal_coeff` to
+ `pylops.optimization.cls_sparsity.OMP`
+* Added `solver` to the input parameters of the `_oneshot`
+ internal methods of `pylops.waveeqprocessing.AcousticWave2D`
+ to avoid recreating it for every shot
+* Added `kwargs_fft` to `pylops.signalprocessing.FFT`,
+ `pylops.signalprocessing.FFT2D`, and
+ `pylops.signalprocessing.FFTND`
+* Fix bug in `pylops.waveeqprocessing.MDD` when using
+ CuPy arrays for `G` and `d` with `twosided=True` and `add_negative=True`
+* Fix bug in `pylops.signalprocessing.FourierRadon3D`
+ in the default choice of `num_threads_per_blocks`
+* Fix bug in `pylops.signalprocessing.Convolve1D`
+ in the definition of `pad` and `padd` when applying the
+ operator to a CuPy array
+* Fix bug in `pylops.optimization.cls_sparsity.OMP` avoiding
+ passing `explicit` in the creation of `_ColumnLinearOperator`
+* Fix bug in `pylops.optimization.cls_sparsity.OMP` callback
+ method as `cols` was not passed not allowing ``x`` to be
+ properly reconstructed
+* Fix bug in `pylops.waveeqprocessing.SeismicInterpolation`
+ in calculation of `sampling` when not passed
+
# 2.4.0
* Added `pylops.signalprocessing.FourierRadon2d` and
`pylops.signalprocessing.FourierRadon3d` operators
diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst
index 43d59cacf..6193c9002 100644
--- a/docs/source/changelog.rst
+++ b/docs/source/changelog.rst
@@ -3,6 +3,37 @@
Changelog
=========
+Version 2.5.0
+-------------
+
+*Released on: 21/06/2025*
+
+* Added `cuda` engine to :py:class:`pylops.waveeqprocessing.Kirchhoff`
+ operator
+* Added `Opbasis` and `optimal_coeff` to
+ :py:class:`pylops.optimization.cls_sparsity.OMP`
+* Added `solver` to the input parameters of the `_oneshot`
+ internal methods of :py:class:`pylops.waveeqprocessing.AcousticWave2D`
+ to avoid recreating it for every shot
+* Added `kwargs_fft` to `pylops.signalprocessing.FFT`,
+ :py:class:`pylops.signalprocessing.FFT2D`, and
+ :py:class:`pylops.signalprocessing.FFTND`
+* Fix bug in :py:func:`pylops.waveeqprocessing.MDD` when using
+ CuPy arrays for `G` and `d` with `twosided=True` and `add_negative=True`
+* Fix bug in :py:class:`pylops.signalprocessing.FourierRadon3D`
+ in the default choice of `num_threads_per_blocks`
+* Fix bug in :py:class:`pylops.signalprocessing.Convolve1D`
+ in the definition of `pad` and `padd` when applying the
+ operator to a CuPy array
+* Fix bug in :py:class:`pylops.optimization.cls_sparsity.OMP` avoiding
+ passing `explicit` in the creation of `_ColumnLinearOperator`
+* Fix bug in :py:class:`pylops.optimization.cls_sparsity.OMP` callback
+ method as `cols` was not passed not allowing ``x`` to be
+ properly reconstructed
+* Fix bug in :py:func:`pylops.waveeqprocessing.SeismicInterpolation`
+ in calculation of `sampling` when not passed
+
+
Version 2.4.0
-------------
@@ -189,7 +220,7 @@ Version 1.18.0
* Extended :py:func:`pylops.Laplacian` to N-dimensional arrays
* Added `forward` kind to :py:class:`pylops.SecondDerivative` and
:py:func:`pylops.Laplacian`
-* Added `chirp-sliding` kind to :py:class:`pylops.waveeqprocessing.seismicinterpolation.SeismicInterpolation`
+* Added `chirp-sliding` kind to :py:func:`pylops.waveeqprocessing.SeismicInterpolation`
* Fixed bug due to the new internal structure of `LinearOperator` submodule introduced in `scipy1.8.0`
@@ -389,7 +420,7 @@ Version 1.9.1
:py:class:`pylops.signalprocessing.FFT2D` to ensure that the type of the input
vector is retained when applying forward and adjoint.
* Added ``dtype`` parameter to the ``FFT`` calls in the definition of the
- :py:class:`pylops.waveeqprocessing.MDD` operation. This ensure that the type
+ :py:func:`pylops.waveeqprocessing.MDD` operation. This ensure that the type
of the real part of ``G`` input is enforced to the output vectors of the
forward and adjoint operations.
diff --git a/docs/source/sg_execution_times.rst b/docs/source/sg_execution_times.rst
new file mode 100644
index 000000000..9641132d2
--- /dev/null
+++ b/docs/source/sg_execution_times.rst
@@ -0,0 +1,271 @@
+
+:orphan:
+
+.. _sphx_glr_sg_execution_times:
+
+
+Computation times
+=================
+**00:00.703** total execution time for 79 files **from all galleries**:
+
+.. container::
+
+ .. raw:: html
+
+
+
+
+
+
+
+ .. list-table::
+ :header-rows: 1
+ :class: table table-striped sg-datatable
+
+ * - Example
+ - Time
+ - Mem (MB)
+ * - :ref:`sphx_glr_tutorials_jaxop.py` (``../../tutorials/jaxop.py``)
+ - 00:00.703
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_avo.py` (``../../examples/plot_avo.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_bayeslinearregr.py` (``../../examples/plot_bayeslinearregr.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_bilinear.py` (``../../examples/plot_bilinear.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_blending.py` (``../../examples/plot_blending.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_causalintegration.py` (``../../examples/plot_causalintegration.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_cgls.py` (``../../examples/plot_cgls.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_chirpradon.py` (``../../examples/plot_chirpradon.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_conj.py` (``../../examples/plot_conj.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_convolve.py` (``../../examples/plot_convolve.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_dct.py` (``../../examples/plot_dct.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_derivative.py` (``../../examples/plot_derivative.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_describe.py` (``../../examples/plot_describe.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_diagonal.py` (``../../examples/plot_diagonal.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_dtcwt.py` (``../../examples/plot_dtcwt.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_fft.py` (``../../examples/plot_fft.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_flip.py` (``../../examples/plot_flip.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_fourierradon.py` (``../../examples/plot_fourierradon.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_identity.py` (``../../examples/plot_identity.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_imag.py` (``../../examples/plot_imag.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_ista.py` (``../../examples/plot_ista.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_l1l1.py` (``../../examples/plot_l1l1.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_linearregr.py` (``../../examples/plot_linearregr.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_matrixmult.py` (``../../examples/plot_matrixmult.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_mdc.py` (``../../examples/plot_mdc.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_multiproc.py` (``../../examples/plot_multiproc.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_nmo.py` (``../../examples/plot_nmo.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_nonstatconvolve.py` (``../../examples/plot_nonstatconvolve.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_nonstatfilter.py` (``../../examples/plot_nonstatfilter.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_pad.py` (``../../examples/plot_pad.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_patching.py` (``../../examples/plot_patching.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_phaseshift.py` (``../../examples/plot_phaseshift.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_prestack.py` (``../../examples/plot_prestack.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_radon.py` (``../../examples/plot_radon.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_real.py` (``../../examples/plot_real.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_regr.py` (``../../examples/plot_regr.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_restriction.py` (``../../examples/plot_restriction.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_roll.py` (``../../examples/plot_roll.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_seislet.py` (``../../examples/plot_seislet.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_seismicevents.py` (``../../examples/plot_seismicevents.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_shift.py` (``../../examples/plot_shift.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_sliding.py` (``../../examples/plot_sliding.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_slopeest.py` (``../../examples/plot_slopeest.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_smoothing1d.py` (``../../examples/plot_smoothing1d.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_smoothing2d.py` (``../../examples/plot_smoothing2d.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_spread.py` (``../../examples/plot_spread.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_stacking.py` (``../../examples/plot_stacking.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_sum.py` (``../../examples/plot_sum.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_symmetrize.py` (``../../examples/plot_symmetrize.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_tapers.py` (``../../examples/plot_tapers.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_tndarray.py` (``../../examples/plot_tndarray.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_transpose.py` (``../../examples/plot_transpose.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_tvreg.py` (``../../examples/plot_tvreg.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_twoway.py` (``../../examples/plot_twoway.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_wavelet.py` (``../../examples/plot_wavelet.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_wavest.py` (``../../examples/plot_wavest.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_wavs.py` (``../../examples/plot_wavs.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_gallery_plot_zero.py` (``../../examples/plot_zero.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_bayesian.py` (``../../tutorials/bayesian.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_classsolvers.py` (``../../tutorials/classsolvers.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_ctscan.py` (``../../tutorials/ctscan.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_deblending.py` (``../../tutorials/deblending.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_deblurring.py` (``../../tutorials/deblurring.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_deghosting.py` (``../../tutorials/deghosting.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_dottest.py` (``../../tutorials/dottest.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_ilsm.py` (``../../tutorials/ilsm.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_interpolation.py` (``../../tutorials/interpolation.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_linearoperator.py` (``../../tutorials/linearoperator.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_lsm.py` (``../../tutorials/lsm.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_marchenko.py` (``../../tutorials/marchenko.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_mdd.py` (``../../tutorials/mdd.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_poststack.py` (``../../tutorials/poststack.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_prestack.py` (``../../tutorials/prestack.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_radonfiltering.py` (``../../tutorials/radonfiltering.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_realcomplex.py` (``../../tutorials/realcomplex.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_seismicinterpolation.py` (``../../tutorials/seismicinterpolation.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_solvers.py` (``../../tutorials/solvers.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_torchop.py` (``../../tutorials/torchop.py``)
+ - 00:00.000
+ - 0.0
+ * - :ref:`sphx_glr_tutorials_wavefielddecomposition.py` (``../../tutorials/wavefielddecomposition.py``)
+ - 00:00.000
+ - 0.0