Documentation Index Fetch the complete documentation index at: https://prod-mint.classiq.io/llms.txt
Use this file to discover all available pages before exploring further.
View on GitHub Open this notebook in GitHub to run it yourself
The quantum Sine and Cosine transforms functions are the quantum analog for the discrete Sine and Cosine transforms.
The unitary versions of the type I and type II transforms are defined as follows:
D C T j k ( 1 ) ( N ) = α j k 2 N − 1 cos ( π j k N − 1 ) , α j k = { 1 2 j = 0 , N − 1 , 1 2 k = 0 , N − 1 , 1 else , j , k = 0 … , N − 1 {\rm DCT}^{(1)}_{jk}(N) = \alpha_{jk}\sqrt{\frac{2}{N-1}} \cos\left(\frac{\pi j k}{N-1}\right), \qquad
\alpha_{jk} = \left\{ \begin{array}{l l}
\frac{1}{\sqrt{2}} & j = 0,N-1 ,\\
\frac{1}{\sqrt{2}} & k = 0,N-1 ,\\
1 & \text{else}
\end{array}
\right.,
\qquad j,k = 0\dots,N-1 DCT jk ( 1 ) ( N ) = α jk N − 1 2 cos ( N − 1 πjk ) , α jk = ⎩ ⎨ ⎧ 2 1 2 1 1 j = 0 , N − 1 , k = 0 , N − 1 , else , j , k = 0 … , N − 1
D S T j k ( 1 ) ( N ) = 2 N + 1 sin ( π j k N + 1 ) , j , k = 0 … , N − 1 {\rm DST}^{(1)}_{jk}(N) = \sqrt{\frac{2}{N+1}} \sin\left(\frac{\pi j k}{N+1}\right), \qquad j,k = 0\dots,N-1 DST jk ( 1 ) ( N ) = N + 1 2 sin ( N + 1 πjk ) , j , k = 0 … , N − 1
D C T j k ( 2 ) ( N ) = α j k 2 N cos ( π ( j + 1 / 2 ) k N ) , α j k = { 1 2 k = 0 , 1 else , j , k = 0 … , N − 1 {\rm DCT}^{(2)}_{jk}(N) = \alpha_{jk}\sqrt{\frac{2}{N}} \cos\left(\frac{\pi (j+1/2) k }{N}\right), \qquad
\alpha_{jk} = \left\{ \begin{array}{l l}
\frac{1}{\sqrt{2}} & k = 0 ,\\
1 & \text{else}
\end{array}
\right.,
\qquad j,k = 0\dots,N-1 DCT jk ( 2 ) ( N ) = α jk N 2 cos ( N π ( j + 1/2 ) k ) , α jk = { 2 1 1 k = 0 , else , j , k = 0 … , N − 1
D S T j k ( 2 ) ( N ) = α j k 2 N sin ( π ( j + 1 / 2 ) ( k + 1 ) N ) , α j k = { 1 2 k = N − 1 , 1 else , j , k = 0 … , N − 1 {\rm DST}^{(2)}_{jk}(N) = \alpha_{jk} \sqrt{\frac{2}{N}} \sin\left(\frac{\pi (j+1/2) (k+1)}{N}\right), \qquad
\alpha_{jk} = \left\{ \begin{array}{l l}
\frac{1}{\sqrt{2}} & k = N-1 ,\\
1 & \text{else}
\end{array}
\right.,
\qquad j,k = 0\dots,N-1 DST jk ( 2 ) ( N ) = α jk N 2 sin ( N π ( j + 1/2 ) ( k + 1 ) ) , α jk = { 2 1 1 k = N − 1 , else , j , k = 0 … , N − 1
The open library includes four functions, following the implementation in Ref. [1 ]:
QCT and QST of type I
Function: qct_qst_type1
Arguments:
The x quantum argument is the quantum state on which we apply the transforms, according to the following unitary on n ≡ n\equiv n ≡ x.len qubits:
( D C T ( 1 ) ( 2 n − 1 + 1 ) 0 0 i D S T ( 1 ) ( 2 n − 1 − 1 ) ) \left(
\begin{array}{ccc|c}
{} &{} &{} \\
{}&{\rm DCT}^{(1)}(2^{n-1}+1) & {}& 0\\
{} &{} &{} \\
\hline
{} & 0 & {} & i{\rm DST}^{(1)}(2^{n-1}-1)
\end{array}
\right) DCT ( 1 ) ( 2 n − 1 + 1 ) 0 0 i DST ( 1 ) ( 2 n − 1 − 1 )
Example
import numpy as np
from classiq import *
NUM_QUBITS = 4
execution_preferences = ExecutionPreferences(
num_shots = 1 ,
backend_preferences = ClassiqBackendPreferences(
backend_name = ClassiqSimulatorBackendNames. SIMULATOR_STATEVECTOR
),
)
np.random.seed( 123 )
cos_data = np.random.rand( 2 ** ( NUM_QUBITS - 1 ) + 1 )
cos_data = cos_data / np.linalg.norm(cos_data)
sin_data = np.random.rand( 2 ** ( NUM_QUBITS - 1 ) - 1 )
sin_data = sin_data / np.linalg.norm(sin_data)
combined_data = np.append(cos_data / np.sqrt( 2 ), sin_data / np.sqrt( 2 ))
@qfunc
def main ( x : Output[QNum]):
prepare_amplitudes(combined_data.tolist(), 0.0 , x)
qct_qst_type1(x)
qmod = create_model(main, execution_preferences = execution_preferences)
result = execute(qprog).result_value()
qct_data = np.zeros( 2 ** ( NUM_QUBITS - 1 ) + 1 ).astype( complex )
qst_data = np.zeros( 2 ** ( NUM_QUBITS - 1 ) - 1 ).astype( complex )
for sample in result.parsed_state_vector:
value = int (sample.state[ "x" ])
if value < 2 ** ( NUM_QUBITS - 1 ) + 1 :
qct_data[value] += sample.amplitude
else :
qst_data[ int (value - 2 ** ( NUM_QUBITS - 1 ) - 1 )] += sample.amplitude
def dct1 ( n ):
dct = np.array(
[
[
np.cos(np.pi * j * k / (n - 1 ))
* (np.sqrt( 1 / 2 ) if j == 0 or j == n - 1 else 1 )
* (np.sqrt( 1 / 2 ) if k == 0 or k == n - 1 else 1 )
for j in range (n)
]
for k in range (n)
]
) / np.sqrt((n - 1 ) / 2 )
return dct
def dst1 ( n ):
dst = np.array(
[
[np.sin(np.pi * (j + 1 ) * (k + 1 ) / (n + 1 )) for j in range (n)]
for k in range (n)
]
) / np.sqrt((n + 1 ) / 2 )
return dst
global_phase = np.exp( 1 j * np.angle(qct_data[ 0 ]))
measured_cos_res = np.real(qct_data / global_phase)
expected_cos_res = (dct1( 2 ** ( NUM_QUBITS - 1 ) + 1 ) @ cos_data) / np.sqrt( 2 )
print ( "measured result:" , measured_cos_res)
print ( "expected result:" , expected_cos_res)
assert np.allclose(measured_cos_res, expected_cos_res, atol = 0.01 )
Output: measured result: [ 0.64936034 -0.13662084 0.02159456 0.08089956 0.06722088 0.18669631
0.02254746 -0.01198615 0.1123771 ]
expected result: [ 0.64936034 -0.13662084 0.02159456 0.08089956 0.06722088 0.18669631
0.02254746 -0.01198615 0.1123771 ]
global_phase = np.exp( 1 j * np.angle(qst_data[ 0 ]))
measured_sin_res = np.real(qst_data / global_phase)
expected_sin_res = (dst1( 2 ** ( NUM_QUBITS - 1 ) - 1 ) @ sin_data) / np.sqrt( 2 )
print ( "measured result:" , measured_sin_res)
print ( "expected result:" , expected_sin_res)
assert np.allclose(measured_sin_res, expected_sin_res, atol = 0.01 )
Output: measured result: [ 0.57556991 0.04712138 0.22433696 -0.27513447 0.17796799 0.07685908
0.05378552]
expected result: [ 0.57556991 0.04712138 0.22433696 -0.27513447 0.17796799 0.07685908
0.05378552]
QCT and QST of type II
Function: qct_qst_type2
Arguments:
The x quantum argument is the quantum state on which we apply the transforms, whereas the single q qubit indicates the block, according to the following unitary on n + 1 ≡ n+1\equiv n + 1 ≡ x.len + 1 +1 + 1 qubits:
( D C T ( 2 ) ( 2 n − 1 ) 0 0 − D S T ( 2 ) ( 2 n − 1 ) ) \left(
\begin{array}{c|c}
{\rm DCT}^{(2)}(2^{n-1}) & 0\\
\hline
0 & -{\rm DST}^{(2)}(2^{n-1})
\end{array}
\right) ( DCT ( 2 ) ( 2 n − 1 ) 0 0 − DST ( 2 ) ( 2 n − 1 ) )
Function: qct_type2
Arguments:
x: QArray[QBit]: the quantum state on which we apply D C T ( 2 ) {\rm DCT}^{(2)} DCT ( 2 ) .
Function: qst_type2
Arguments:
x: QArray[QBit]: the quantum state on which we apply D S T ( 2 ) {\rm DST}^{(2)} DST ( 2 ) .
Example
NUM_QUBITS = 4
cos_sin_data = np.random.rand( 2 ** ( NUM_QUBITS - 1 ))
cos_sin_data = cos_sin_data / np.linalg.norm(cos_sin_data)
@qfunc
def main ( x : Output[QNum], q : Output[QBit]):
prepare_amplitudes(cos_sin_data.tolist(), 0.0 , x)
allocate(q)
H(q)
qct_qst_type2(x, q)
qmod = create_model(main, execution_preferences = execution_preferences)
result = execute(qprog).result_value()
qct_data = np.zeros( 2 ** ( NUM_QUBITS - 1 )).astype( complex )
qst_data = np.zeros( 2 ** ( NUM_QUBITS - 1 )).astype( complex )
for sample in result.parsed_state_vector:
if sample.state[ "q" ] == 0 :
qct_data[ int (sample.state[ "x" ])] += sample.amplitude
else :
qst_data[ int (sample.state[ "x" ])] += sample.amplitude
def dct2 ( n ):
dct = np.array(
[
[
np.cos(np.pi * j * (k + 1 / 2 ) / n) * (np.sqrt( 1 / 2 ) if j == 0 else 1 )
for j in range (n)
]
for k in range (n)
]
) / np.sqrt(n / 2 )
return dct.T
def dst2 ( n ):
dst = np.array(
[
[
np.sin(np.pi * (j + 1 ) * (k + 1 / 2 ) / n)
* (np.sqrt( 1 / 2 ) if j == n - 1 else 1 )
for j in range (n)
]
for k in range (n)
]
) / np.sqrt(n / 2 )
return dst.T
global_phase = np.exp( 1 j * np.angle(qct_data[ 0 ]))
measured_cos_res = np.real(qct_data / global_phase)
expected_cos_res = (dct2( 2 ** ( NUM_QUBITS - 1 )) @ cos_sin_data) / np.sqrt( 2 )
print ( "measured result:" , measured_cos_res)
print ( "expected result:" , expected_cos_res)
assert np.allclose(measured_cos_res, expected_cos_res, atol = 0.01 )
Output: measured result: [ 0.65104654 -0.23305325 -0.11473439 0.02595719 -0.04930425 0.03323495
0.06553173 0.01252819]
expected result: [ 0.65104654 -0.23305325 -0.11473439 0.02595719 -0.04930425 0.03323495
0.06553173 0.01252819]
global_phase = np.exp( 1 j * np.angle(qst_data[ 0 ]))
measured_sin_res = np.real(qst_data / global_phase)
expected_sin_res = (dst2( 2 ** ( NUM_QUBITS - 1 )) @ cos_sin_data) / np.sqrt( 2 )
print ( "measured result:" , measured_sin_res)
print ( "expected result:" , expected_sin_res)
assert np.allclose(measured_sin_res, expected_sin_res, atol = 0.01 )
Output: measured result: [ 0.63981132 -0.2180174 0.13530848 -0.08552637 0.02796936 -0.03450769
0.12370004 -0.01455965]
expected result: [ 0.63981132 -0.2180174 0.13530848 -0.08552637 0.02796936 -0.03450769
0.12370004 -0.01455965]
@qfunc
def main ( x : Output[QNum]):
prepare_amplitudes(cos_sin_data.tolist(), 0.0 , x)
qct_type2(x)
qmod = create_model(main, execution_preferences = execution_preferences)
qprog = synthesize(qmod)
result = execute(qprog).result_value()
qct_data = np.zeros( 2 ** ( NUM_QUBITS - 1 )).astype( complex )
for sample in result.parsed_state_vector:
qct_data[ int (sample.state[ "x" ])] += sample.amplitude
global_phase = np.exp( 1 j * np.angle(qct_data[ 0 ]))
measured_cos_res = np.real(qct_data / global_phase)
expected_cos_res = dct2( 2 ** ( NUM_QUBITS - 1 )) @ cos_sin_data
print ( "measured result:" , measured_cos_res)
print ( "expected result:" , expected_cos_res)
assert np.allclose(measured_cos_res, expected_cos_res, atol = 0.01 )
Output: measured result: [ 0.92071884 -0.32958707 -0.16225893 0.03670901 -0.06972674 0.04700132
0.09267587 0.01771754]
expected result: [ 0.92071884 -0.32958707 -0.16225893 0.03670901 -0.06972674 0.04700132
0.09267587 0.01771754]
@qfunc
def main ( x : Output[QNum]):
prepare_amplitudes(cos_sin_data.tolist(), 0.0 , x)
qst_type2(x)
qmod = create_model(main, execution_preferences = execution_preferences)
qprog = synthesize(qmod)
result = execute(qprog).result_value()
qst_data = np.zeros( 2 ** ( NUM_QUBITS - 1 )).astype( complex )
for sample in result.parsed_state_vector:
qst_data[ int (sample.state[ "x" ])] += sample.amplitude
global_phase = np.exp( 1 j * np.angle(qst_data[ 0 ]))
measured_sin_res = np.real(qst_data / global_phase)
expected_sin_res = dst2( 2 ** ( NUM_QUBITS - 1 )) @ cos_sin_data
print ( "measured result:" , measured_sin_res)
print ( "expected result:" , expected_sin_res)
assert np.allclose(measured_sin_res, expected_sin_res, atol = 0.01 )
Output: measured result: [ 0.90482984 -0.30832317 0.19135509 -0.12095255 0.03955464 -0.04880124
0.17493827 -0.02059046]
expected result: [ 0.90482984 -0.30832317 0.19135509 -0.12095255 0.03955464 -0.04880124
0.17493827 -0.02059046]
References
[1] : Klappenecker, A., & Rotteler M., “Discrete Cosine Transforms on Quantum Computers”.