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

Qiskit / qiskit / 13809362258

12 Mar 2025 10:39AM UTC coverage: 88.142% (+1.0%) from 87.154%
13809362258

Pull #13961

github

web-flow
Merge d9b43a10f into 61076860a
Pull Request #13961: Add explicit tests for MCX synthesis algorithms

72667 of 82443 relevant lines covered (88.14%)

513887.58 hits per line

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

87.65
/qiskit/visualization/array.py
1
# This code is part of Qiskit.
2
#
3
# (C) Copyright IBM 2017, 2020.
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
Tools to create LaTeX arrays.
14
"""
15

16
import numpy as np
1✔
17

18
from qiskit.exceptions import MissingOptionalLibraryError
1✔
19
from qiskit.utils.optionals import HAS_SYMPY
1✔
20

21

22
@HAS_SYMPY.require_in_call("Create a latex representation of a ket expression")
1✔
23
def _num_to_latex(raw_value, decimals=15, first_term=True, coefficient=False):
1✔
24
    """Convert a complex number to latex code suitable for a ket expression
25

26
    Args:
27
        raw_value (complex): Value to convert.
28
        decimals (int): Number of decimal places to round to (default 15).
29
        coefficient (bool): Whether the number is to be used as a coefficient
30
                            of a ket.
31
        first_term (bool): If a coefficient, whether this number is the first
32
                           coefficient in the expression.
33
    Returns:
34
        str: latex code
35
    """
36
    import sympy  # runtime import
1✔
37

38
    raw_value = np.around(raw_value, decimals=decimals).item()
1✔
39
    value = sympy.nsimplify(raw_value, rational=False)
1✔
40

41
    if isinstance(value, sympy.core.numbers.Rational) and value.denominator > 50:
1✔
42
        # Avoid showing ugly fractions (e.g. 50498971964399/62500000000000)
43
        value = value.evalf()  # Display as float
×
44

45
    if isinstance(value, sympy.core.numbers.Float):
1✔
46
        value = round(value, decimals)
1✔
47

48
    element = sympy.latex(value, full_prec=False)
1✔
49

50
    if not coefficient:
1✔
51
        return element
1✔
52

53
    if isinstance(value, sympy.core.Add):
1✔
54
        # element has two terms
55
        element = f"({element})"
×
56

57
    if element == "1":
1✔
58
        element = ""
1✔
59

60
    if element == "-1":
1✔
61
        element = "-"
×
62

63
    if not first_term and not element.startswith("-"):
1✔
64
        element = f"+{element}"
1✔
65

66
    return element
1✔
67

68

69
def _matrix_to_latex(matrix, decimals=10, prefix="", max_size=(8, 8)):
1✔
70
    """Latex representation of a complex numpy array (with maximum dimension 2)
71

72
    Args:
73
        matrix (ndarray): The matrix to be converted to latex, must have dimension 2.
74
        decimals (int): For numbers not close to integers, the number of decimal places
75
                         to round to.
76
        prefix (str): Latex string to be prepended to the latex, intended for labels.
77
        max_size (list(```int```)): Indexable containing two integers: Maximum width and maximum
78
                          height of output Latex matrix (including dots characters). If the
79
                          width and/or height of matrix exceeds the maximum, the centre values
80
                          will be replaced with dots. Maximum width or height must be greater
81
                          than 3.
82

83
    Returns:
84
        str: Latex representation of the matrix
85

86
    Raises:
87
        ValueError: If minimum value in max_size < 3
88
        MissingOptionalLibraryError: If sympy is not installed
89
    """
90
    if min(max_size) < 3:
1✔
91
        raise ValueError("""Smallest value in max_size must be greater than or equal to 3""")
×
92

93
    out_string = f"\n{prefix}\n"
1✔
94
    out_string += "\\begin{bmatrix}\n"
1✔
95

96
    def _elements_to_latex(elements):
1✔
97
        # Takes a list of elements (a row) and creates a latex
98
        # string from it; Each element separated by `&`
99
        el_string = ""
1✔
100
        for el in elements:
1✔
101
            num_string = _num_to_latex(el, decimals=decimals)
1✔
102
            el_string += num_string + " & "
1✔
103
        el_string = el_string[:-2]  # remove trailing ampersands
1✔
104
        return el_string
1✔
105

106
    def _rows_to_latex(rows, max_width):
1✔
107
        # Takes a list of lists (list of 'rows') and creates a
108
        # latex string from it
109
        row_string = ""
1✔
110
        for r in rows:
1✔
111
            if len(r) <= max_width:
1✔
112
                row_string += _elements_to_latex(r)
1✔
113
            else:
114
                row_string += _elements_to_latex(r[: max_width // 2])
1✔
115
                row_string += "& \\cdots & "
1✔
116
                row_string += _elements_to_latex(r[-max_width // 2 + 1 :])
1✔
117
            row_string += " \\\\\n "
1✔
118
        return row_string
1✔
119

120
    max_width, max_height = max_size
1✔
121
    if matrix.ndim == 1:
1✔
122
        out_string += _rows_to_latex([matrix], max_width)
1✔
123

124
    elif len(matrix) > max_height:
1✔
125
        # We need to truncate vertically, so we process the rows at the beginning
126
        # and end, and add a line of vertical elipse (dots) characters between them
127
        out_string += _rows_to_latex(matrix[: max_height // 2], max_width)
1✔
128

129
        if max_width >= matrix.shape[1]:
1✔
130
            out_string += "\\vdots & " * matrix.shape[1]
×
131
        else:
132
            # In this case we need to add the diagonal dots in line with the column
133
            # of horizontal dots
134
            pre_vdots = max_width // 2
1✔
135
            post_vdots = max_width // 2 + np.mod(max_width, 2) - 1
1✔
136
            out_string += "\\vdots & " * pre_vdots
1✔
137
            out_string += "\\ddots & "
1✔
138
            out_string += "\\vdots & " * post_vdots
1✔
139

140
        out_string = out_string[:-2] + "\\\\\n "
1✔
141
        out_string += _rows_to_latex(matrix[-max_height // 2 + 1 :], max_width)
1✔
142

143
    else:
144
        out_string += _rows_to_latex(matrix, max_width)
1✔
145
    out_string += "\\end{bmatrix}\n"
1✔
146
    return out_string
1✔
147

148

149
def array_to_latex(array, precision=10, prefix="", source=False, max_size=8):
1✔
150
    """Latex representation of a complex numpy array (with dimension 1 or 2)
151

152
    Args:
153
        array (ndarray): The array to be converted to latex, must have dimension 1 or 2 and
154
                         contain only numerical data.
155
        precision (int): For numbers not close to integers or common terms, the number of
156
                         decimal places to round to.
157
        prefix (str): Latex string to be prepended to the latex, intended for labels.
158
        source (bool): If ``False``, will return IPython.display.Latex object. If display is
159
                       ``True``, will instead return the LaTeX source string.
160
        max_size (list(int) or int): The maximum size of the output Latex array.
161

162
            * If list(``int``), then the 0th element of the list specifies the maximum
163
              width (including dots characters) and the 1st specifies the maximum height
164
              (also inc. dots characters).
165
            * If a single ``int`` then this value sets the maximum width _and_ maximum
166
              height.
167

168
    Returns:
169
        str or IPython.display.Latex: If ``source`` is ``True``, a ``str`` of the LaTeX
170
            representation of the array, else an ``IPython.display.Latex`` representation of
171
            the array.
172

173
    Raises:
174
        TypeError: If array can not be interpreted as a numerical numpy array.
175
        ValueError: If the dimension of array is not 1 or 2.
176
        MissingOptionalLibraryError: If ``source`` is ``False`` and ``IPython.display.Latex`` cannot be
177
                     imported. Or if sympy is not installed.
178
    """
179
    try:
1✔
180
        array = np.asarray(array)
1✔
181
        _ = array[0] + 1  # Test first element contains numerical data
1✔
182
    except TypeError as err:
×
183
        raise TypeError(
×
184
            """array_to_latex can only convert numpy arrays containing numerical data,
185
        or types that can be converted to such arrays"""
186
        ) from err
187

188
    if array.ndim > 2:
1✔
189
        raise ValueError("array_to_latex can only convert numpy ndarrays of dimension 1 or 2")
×
190

191
    if isinstance(max_size, int):
1✔
192
        max_size = (max_size, max_size)
1✔
193

194
    outstr = _matrix_to_latex(array, decimals=precision, prefix=prefix, max_size=max_size)
1✔
195

196
    if source is True:
1✔
197
        return outstr
1✔
198

199
    try:
1✔
200
        from IPython.display import Latex
1✔
201
    except ImportError as err:
×
202
        raise MissingOptionalLibraryError(
×
203
            libname="IPython",
204
            name="array_to_latex",
205
            pip_install="pip install ipython",
206
        ) from err
207
    return Latex(f"$${outstr}$$")
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