@@ -1108,23 +1108,51 @@ def calculate_cumulant_function(
1108
1108
cumulant_function [..., 1 :, 1 :] -= frequency_shifts [..., 1 :, 1 :]
1109
1109
cumulant_function [..., 1 :, 1 :] += frequency_shifts [..., 1 :, 1 :].swapaxes (- 1 , - 2 )
1110
1110
else :
1111
- # Multi qubit case. Use general expression. Drop imaginary part since
1112
- # result is guaranteed to be real (if we didn't do anything wrong)
1111
+ # Multi qubit case. Use general expression.
1113
1112
traces = pulse .basis .four_element_traces
1113
+ # g_iklj = (
1114
+ # + traces.transpose(0, 1, 2, 3)
1115
+ # - traces.transpose(0, 1, 3, 2)
1116
+ # - traces.transpose(0, 3, 1, 2)
1117
+ # + traces.transpose(0, 3, 2, 1)
1118
+ # )
1119
+ # g_jikl = (
1120
+ # + traces.transpose(3, 0, 1, 2)
1121
+ # - traces.transpose(2, 0, 1, 3)
1122
+ # - traces.transpose(2, 0, 3, 1)
1123
+ # + traces.transpose(1, 0, 3, 2)
1124
+ # )
1114
1125
cumulant_function = - (
1115
1126
+ oe .contract ('...kl,klji->...ij' , decay_amplitudes , traces , backend = 'sparse' )
1116
1127
- oe .contract ('...kl,kjli->...ij' , decay_amplitudes , traces , backend = 'sparse' )
1117
1128
- oe .contract ('...kl,kilj->...ij' , decay_amplitudes , traces , backend = 'sparse' )
1118
1129
+ oe .contract ('...kl,kijl->...ij' , decay_amplitudes , traces , backend = 'sparse' )
1119
1130
) / 2
1120
1131
if second_order :
1132
+ # f_iklj = (
1133
+ # + traces.transpose(0, 1, 2, 3)
1134
+ # - traces.transpose(0, 2, 1, 3)
1135
+ # - traces.transpose(0, 2, 3, 1)
1136
+ # + traces.transpose(0, 3, 2, 1)
1137
+ # )
1138
+ #
1139
+ # f_iklj = -g_iljk:
1140
+ # f = -g.transpose(0, 2, 3, 1)
1141
+ #
1142
+ # f_jikl = (
1143
+ # + traces.transpose(3, 0, 1, 2)
1144
+ # - traces.transpose(3, 0, 2, 1)
1145
+ # - traces.transpose(1, 0, 2, 3)
1146
+ # + traces.transpose(1, 0, 3, 2)
1147
+ # )
1121
1148
cumulant_function -= (
1122
1149
+ oe .contract ('...kl,klji->...ij' , frequency_shifts , traces , backend = 'sparse' )
1123
1150
- oe .contract ('...kl,lkji->...ij' , frequency_shifts , traces , backend = 'sparse' )
1124
1151
- oe .contract ('...kl,klij->...ij' , frequency_shifts , traces , backend = 'sparse' )
1125
1152
+ oe .contract ('...kl,lkij->...ij' , frequency_shifts , traces , backend = 'sparse' )
1126
1153
) / 2
1127
1154
1155
+ # Drop imaginary part since result is guaranteed to be real (if we didn't do anything wrong)
1128
1156
return cumulant_function .real
1129
1157
1130
1158
@@ -1851,17 +1879,20 @@ def infidelity(
1851
1879
The ``PulseSequence`` instance for which to calculate the
1852
1880
infidelity for.
1853
1881
spectrum: array_like, shape ([[n_nops,] n_nops,] omega) or callable
1854
- The two-sided noise power spectral density in units of inverse
1855
- frequencies as an array of shape (n_omega,), (n_nops, n_omega),
1856
- or (n_nops, n_nops, n_omega). In the first case, the same
1857
- spectrum is taken for all noise operators, in the second, it is
1858
- assumed that there are no correlations between different noise
1859
- sources and thus there is one spectrum for each noise operator.
1882
+ The noise power spectral density in units of inverse frequencies
1883
+ as an array of shape (n_omega,), (n_nops, n_omega), or
1884
+ (n_nops, n_nops, n_omega). In the first case, the same spectrum
1885
+ is taken for all noise operators, in the second, it is assumed
1886
+ that there are no correlations between different noise sources
1887
+ and thus there is one spectrum for each noise operator.
1860
1888
In the third and most general case, there may be a spectrum for
1861
1889
each pair of noise operators corresponding to the correlations
1862
1890
between them. n_nops is the number of noise operators considered
1863
1891
and should be equal to ``len(n_oper_identifiers)``.
1864
1892
1893
+ See :ref:`Notes <notes>` for a discussion on one- and two-sided
1894
+ power spectral densities.
1895
+
1865
1896
If *test_convergence* is ``True``, a function handle to
1866
1897
compute the power spectral density from a sequence of
1867
1898
frequencies is expected.
@@ -1946,15 +1977,34 @@ def infidelity(
1946
1977
infidelities that can be computed by setting
1947
1978
``which='correlations'``.
1948
1979
1980
+ **One- and two-sided spectral densities**
1949
1981
1950
- To convert to the average gate infidelity, use the
1951
- following relation given by Horodecki et al. [Hor99]_ and
1952
- Nielsen [Nie02]_:
1982
+ Since the real (imaginary) part of filter function :math:`F(\omega)`
1983
+ is even (odd), it does not matter for integral whether
1984
+ :math:`S(\omega)` is taken to be the one- or two-sided spectral
1985
+ density. However, care should be taken that, if it is one or the
1986
+ other, the frequencies :math:`\omega` are positive or symmetric
1987
+ about zero, respectively.
1988
+
1989
+ To convert between one- and two-sided PSDs, use the following
1990
+ relationship:
1991
+
1992
+ .. math::
1993
+
1994
+ S_\mathrm{onesided}(\omega) = 2 S_\mathrm{twosided}(\omega).
1995
+
1996
+ **Conversion to the Average Gate Infidelity (AGI)**
1997
+
1998
+ To convert the entanglement infidelity to the average gate
1999
+ infidelity, use the following relation given by Horodecki et al.
2000
+ [Hor99]_ and Nielsen [Nie02]_:
1953
2001
1954
2002
.. math::
1955
2003
1956
2004
\mathcal{I}_\mathrm{avg} = \frac{d}{d+1}\mathcal{I}.
1957
2005
2006
+ **Goodness of approximation**
2007
+
1958
2008
The smallness parameter is given by
1959
2009
1960
2010
.. math::
0 commit comments