• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Qiskit / qiskit / 13141756872

04 Feb 2025 05:55PM UTC coverage: 88.857% (+0.03%) from 88.826%
13141756872

Pull #13758

github

web-flow
Merge 2b682651b into 8095ace7e
Pull Request #13758: Support `SparseObservable` to `SparsePauliOp` conversions

75 of 77 new or added lines in 2 files covered. (97.4%)

129 existing lines in 12 files now uncovered.

79818 of 89827 relevant lines covered (88.86%)

349256.24 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.33
/qiskit/providers/basic_provider/basic_provider_tools.py
1
# This code is part of Qiskit.
2
#
3
# (C) Copyright IBM 2017, 2023.
4
#
5
# This code is licensed under the Apache License, Version 2.0. You may
6
# obtain a copy of this license in the LICENSE.txt file in the root directory
7
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8
#
9
# Any modifications or derivative works of this code must retain this
10
# copyright notice, and modified files need to carry a notice indicating
11
# that they have been altered from the originals.
12

13
"""Contains functions used by the basic provider simulators.
14

15
"""
16
from __future__ import annotations
1✔
17

18
from string import ascii_uppercase, ascii_lowercase
1✔
19

20
import numpy as np
1✔
21

22
import qiskit.circuit.library.standard_gates as gates
1✔
23
from qiskit.exceptions import QiskitError
1✔
24

25
# Single qubit gates supported by ``single_gate_params``.
26
SINGLE_QUBIT_GATES = {
1✔
27
    "U": gates.UGate,
28
    "u": gates.UGate,
29
    "u1": gates.U1Gate,
30
    "u2": gates.U2Gate,
31
    "u3": gates.U3Gate,
32
    "h": gates.HGate,
33
    "p": gates.PhaseGate,
34
    "s": gates.SGate,
35
    "sdg": gates.SdgGate,
36
    "sx": gates.SXGate,
37
    "sxdg": gates.SXdgGate,
38
    "t": gates.TGate,
39
    "tdg": gates.TdgGate,
40
    "x": gates.XGate,
41
    "y": gates.YGate,
42
    "z": gates.ZGate,
43
    "id": gates.IGate,
44
    "i": gates.IGate,
45
    "r": gates.RGate,
46
    "rx": gates.RXGate,
47
    "ry": gates.RYGate,
48
    "rz": gates.RZGate,
49
}
50

51

52
def single_gate_matrix(gate: str, params: list[float] | None = None) -> np.ndarray:
1✔
53
    """Get the matrix for a single qubit.
54

55
    Args:
56
        gate: the single qubit gate name
57
        params: the operation parameters op['params']
58
    Returns:
59
        array: A numpy array representing the matrix
60
    Raises:
61
        QiskitError: If a gate outside the supported set is passed in for the
62
            ``Gate`` argument.
63
    """
64
    if params is None:
1✔
UNCOV
65
        params = []
×
66
    if gate in SINGLE_QUBIT_GATES:
1✔
67
        gc = SINGLE_QUBIT_GATES[gate]
1✔
68
    else:
69
        raise QiskitError(f"Gate is not a valid basis gate for this simulator: {gate}")
×
70

71
    return gc(*params).to_matrix()
1✔
72

73

74
# Two qubit gates WITHOUT parameters: name -> matrix
75
TWO_QUBIT_GATES = {
1✔
76
    "CX": gates.CXGate().to_matrix(),
77
    "cx": gates.CXGate().to_matrix(),
78
    "ecr": gates.ECRGate().to_matrix(),
79
    "cy": gates.CYGate().to_matrix(),
80
    "cz": gates.CZGate().to_matrix(),
81
    "swap": gates.SwapGate().to_matrix(),
82
    "iswap": gates.iSwapGate().to_matrix(),
83
    "ch": gates.CHGate().to_matrix(),
84
    "cs": gates.CSGate().to_matrix(),
85
    "csdg": gates.CSdgGate().to_matrix(),
86
    "csx": gates.CSXGate().to_matrix(),
87
    "dcx": gates.DCXGate().to_matrix(),
88
}
89

90
# Two qubit gates WITH parameters: name -> class
91
TWO_QUBIT_GATES_WITH_PARAMETERS = {
1✔
92
    "cp": gates.CPhaseGate,
93
    "crx": gates.CRXGate,
94
    "cry": gates.CRYGate,
95
    "crz": gates.CRZGate,
96
    "cu": gates.CUGate,
97
    "cu1": gates.CU1Gate,
98
    "cu3": gates.CU3Gate,
99
    "rxx": gates.RXXGate,
100
    "ryy": gates.RYYGate,
101
    "rzz": gates.RZZGate,
102
    "rzx": gates.RZXGate,
103
    "xx_minus_yy": gates.XXMinusYYGate,
104
    "xx_plus_yy": gates.XXPlusYYGate,
105
}
106

107

108
# Three qubit gates: name -> matrix
109
THREE_QUBIT_GATES = {
1✔
110
    "ccx": gates.CCXGate().to_matrix(),
111
    "ccz": gates.CCZGate().to_matrix(),
112
    "rccx": gates.RCCXGate().to_matrix(),
113
    "cswap": gates.CSwapGate().to_matrix(),
114
}
115

116

117
def einsum_matmul_index(gate_indices: list[int], number_of_qubits: int) -> str:
1✔
118
    """Return the index string for Numpy.einsum matrix-matrix multiplication.
119

120
    The returned indices are to perform a matrix multiplication A.B where
121
    the matrix A is an M-qubit matrix, matrix B is an N-qubit matrix, and
122
    M <= N, and identity matrices are implied on the subsystems where A has no
123
    support on B.
124

125
    Args:
126
        gate_indices (list[int]): the indices of the right matrix subsystems
127
                                   to contract with the left matrix.
128
        number_of_qubits (int): the total number of qubits for the right matrix.
129

130
    Returns:
131
        str: An indices string for the Numpy.einsum function.
132
    """
133

134
    mat_l, mat_r, tens_lin, tens_lout = _einsum_matmul_index_helper(gate_indices, number_of_qubits)
×
135

136
    # Right indices for the N-qubit input and output tensor
137
    tens_r = ascii_uppercase[:number_of_qubits]
×
138

139
    # Combine indices into matrix multiplication string format
140
    # for numpy.einsum function
141
    return f"{mat_l}{mat_r}, {tens_lin}{tens_r}->{tens_lout}{tens_r}"
×
142

143

144
def einsum_vecmul_index(gate_indices: list[int], number_of_qubits: int) -> str:
1✔
145
    """Return the index string for Numpy.einsum matrix-vector multiplication.
146

147
    The returned indices are to perform a matrix multiplication A.v where
148
    the matrix A is an M-qubit matrix, vector v is an N-qubit vector, and
149
    M <= N, and identity matrices are implied on the subsystems where A has no
150
    support on v.
151

152
    Args:
153
        gate_indices (list[int]): the indices of the right matrix subsystems
154
                                  to contract with the left matrix.
155
        number_of_qubits (int): the total number of qubits for the right matrix.
156

157
    Returns:
158
        str: An indices string for the Numpy.einsum function.
159
    """
160

161
    mat_l, mat_r, tens_lin, tens_lout = _einsum_matmul_index_helper(gate_indices, number_of_qubits)
1✔
162

163
    # Combine indices into matrix multiplication string format
164
    # for numpy.einsum function
165
    return f"{mat_l}{mat_r}, {tens_lin}->{tens_lout}"
1✔
166

167

168
def _einsum_matmul_index_helper(
1✔
169
    gate_indices: list[int], number_of_qubits: int
170
) -> tuple[str, str, str, str]:
171
    """Return the index string for Numpy.einsum matrix multiplication.
172

173
    The returned indices are to perform a matrix multiplication A.v where
174
    the matrix A is an M-qubit matrix, matrix v is an N-qubit vector, and
175
    M <= N, and identity matrices are implied on the subsystems where A has no
176
    support on v.
177

178
    Args:
179
        gate_indices (list[int]): the indices of the right matrix subsystems
180
                                   to contract with the left matrix.
181
        number_of_qubits (int): the total number of qubits for the right matrix.
182

183
    Returns:
184
        tuple: (mat_left, mat_right, tens_in, tens_out) of index strings for
185
        that may be combined into a Numpy.einsum function string.
186

187
    Raises:
188
        QiskitError: if the total number of qubits plus the number of
189
        contracted indices is greater than 26.
190
    """
191

192
    # Since we use ASCII alphabet for einsum index labels we are limited
193
    # to 26 total free left (lowercase) and 26 right (uppercase) indexes.
194
    # The rank of the contracted tensor reduces this as we need to use that
195
    # many characters for the contracted indices
196
    if len(gate_indices) + number_of_qubits > 26:
1✔
197
        raise QiskitError("Total number of free indexes limited to 26")
×
198

199
    # Indices for N-qubit input tensor
200
    tens_in = ascii_lowercase[:number_of_qubits]
1✔
201

202
    # Indices for the N-qubit output tensor
203
    tens_out = list(tens_in)
1✔
204

205
    # Left and right indices for the M-qubit multiplying tensor
206
    mat_left = ""
1✔
207
    mat_right = ""
1✔
208

209
    # Update left indices for mat and output
210
    for pos, idx in enumerate(reversed(gate_indices)):
1✔
211
        mat_left += ascii_lowercase[-1 - pos]
1✔
212
        mat_right += tens_in[-1 - idx]
1✔
213
        tens_out[-1 - idx] = ascii_lowercase[-1 - pos]
1✔
214
    tens_out = "".join(tens_out)
1✔
215

216
    # Combine indices into matrix multiplication string format
217
    # for numpy.einsum function
218
    return mat_left, mat_right, tens_in, tens_out
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc