Source code for qrisp.algorithms.gqsp.convolution
"""
********************************************************************************
* Copyright (c) 2026 the Qrisp authors
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License, v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is
* available at https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************
"""
import numpy as np
from qrisp import (
QuantumVariable,
QuantumBool,
)
from qrisp.alg_primitives import gidney_adder
from qrisp.algorithms.gqsp.gqsp import GQSP
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from jax.typing import ArrayLike
# https://journals.aps.org/prxquantum/pdf/10.1103/PRXQuantum.5.020368
[docs]
def convolve(qarg: QuantumVariable, weights: "ArrayLike") -> QuantumBool:
r"""
Performs cyclic convolution of a quantum state with a filter.
Given $\ket{\psi}=\sum_{j=0}^{N-1}x_j\ket{j}$ and a filter $f=\{a_k\}_{k=-d}^d$
the cyclic convolution of $\ket{\psi}$ with $f$ is
.. math::
\ket{\psi \star f} = \sum_{m=0}^{N-1}(\psi \star f)_m\ket{m}
where
.. math::
(\psi \star f)_m = \sum_{k=-d}^d a_k x_{[m-k \mod N]}
Parameters
----------
qarg : QuantumVariable
Variable representing the input signal.
weights : ArrayLike, shape (2d+1,)
The filter coefficients for the cyclic convolution.
These are applied as a sliding window across the signal,
where the middle element corresponds to the weight of the current index.
Returns
-------
QuantumBool
Auxiliary variable after applying the GQSP protocol.
Must be measured in state $\ket{0}$ for the GQSP protocol to be successful.
Notes
-----
- Performs a cyclic convolution on the quantum signal,
effectively applying a local filtering operation such as an $n$-point smoothing.
Examples
--------
::
import numpy as np
from qrisp import *
from qrisp.gqsp import convolve
from scipy.ndimage import convolve as sp_convolve
# A simple square wave signal
psi = np.array([1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0])
# A simple 3-point smoothing filter {a_{-1}, a_0, a_1} = {0.25, 0.5, 0.25}
f = np.array([0.25, 0.5, 0.25])
# Mode 'wrap' performs cyclic convolution
convolved_signal_target = sp_convolve(psi, f, mode='wrap')
print("target:", convolved_signal_target)
# target: [0.75 1. 1. 0.75 0.25 0. 0. 0.25]
def psi_prep():
qv = QuantumFloat(3)
prepare(qv, psi)
return qv
# Converts the function to be executed within a
# repeat-until-success (RUS) procedure.
@RUS
def conv_psi_prep():
qarg = psi_prep()
anc = convolve(qarg, f)
success_bool = measure(anc) == 0
reset(anc)
anc.delete()
return success_bool, qarg
# The terminal_sampling decorator performs a hybrid simulation,
# and afterwards samples from the resulting quantum state.
@terminal_sampling
def main():
psi_conv = conv_psi_prep()
return psi_conv
res_dict = main()
max_ = max(res_dict.values())
convolved_signal_qsp = np.sqrt([res_dict.get(key,0) / max_ for key in range(8)])
print("qsp:", convolved_signal_qsp)
# qsp: [0.7499999 , 1. , 1. , 0.74999996, 0.24999994,
# 0. , 0. , 0.25000007])
"""
def U(qv):
gidney_adder(1, qv)
d = len(weights) // 2
anc = QuantumBool()
GQSP(anc, qarg, unitary=U, p=weights, k=d)
return anc