def yzy_to_zyz(xi, theta1, theta2, eps=1e-9):  # pylint: disable=invalid-name
        """Express a Y.Z.Y single qubit gate as a Z.Y.Z gate.

        Solve the equation

        .. math::

        Ry(theta1).Rz(xi).Ry(theta2) = Rz(phi).Ry(theta).Rz(lambda)

        for theta, phi, and lambda.

        Return a solution theta, phi, and lambda.
        """
        quaternion_yzy = quaternion_from_euler([theta1, xi, theta2], 'yzy')
        euler = quaternion_yzy.to_zyz()
        quaternion_zyz = quaternion_from_euler(euler, 'zyz')
        # output order different than rotation order
        out_angles = (euler[1], euler[0], euler[2])
        abs_inner = abs(quaternion_zyz.data.dot(quaternion_yzy.data))
        if not np.allclose(abs_inner, 1, eps):
            raise TranspilerError('YZY and ZYZ angles do not give same rotation matrix.')
        out_angles = tuple(0 if np.abs(angle) < _CHOP_THRESHOLD else angle
                           for angle in out_angles)
        return out_angles

Express a Y . Z . Y single qubit gate as a Z . Y . Z gate .


def _validate_input_state(quantum_state):
    """Validates the input to state visualization functions.

    Args:
        quantum_state (ndarray): Input state / density matrix.
    Returns:
        rho: A 2d numpy array for the density matrix.
    Raises:
        VisualizationError: Invalid input.
    """
    rho = np.asarray(quantum_state)
    if rho.ndim == 1:
        rho = np.outer(rho, np.conj(rho))
    # Check the shape of the input is a square matrix
    shape = np.shape(rho)
    if len(shape) != 2 or shape[0] != shape[1]:
        raise VisualizationError("Input is not a valid quantum state.")
    # Check state is an n-qubit state
    num = int(np.log2(rho.shape[0]))
    if 2 ** num != rho.shape[0]:
        raise VisualizationError("Input is not a multi-qubit quantum state.")
    return rho

Validates the input to state visualization functions .


def _trim(image):
    """Trim a PIL image and remove white space."""
    background = PIL.Image.new(image.mode, image.size, image.getpixel((0, 0)))
    diff = PIL.ImageChops.difference(image, background)
    diff = PIL.ImageChops.add(diff, diff, 2.0, -100)
    bbox = diff.getbbox()
    if bbox:
        image = image.crop(bbox)
    return image

def _trim ( image ) : background = PIL . Image . new ( image . mode , image . size , image . getpixel ( ( 0 , 0 ) ) ) diff = PIL . ImageChops . difference ( image , background ) diff = PIL . ImageChops . add ( diff , diff , 2.0 , - 100 ) bbox = diff . getbbox ( ) if bbox : image = image . crop ( bbox ) return image

Trim a PIL image and remove white space .


def _get_gate_span(qregs, instruction):
    """Get the list of qubits drawing this gate would cover"""

    min_index = len(qregs)
    max_index = 0
    for qreg in instruction.qargs:
        index = qregs.index(qreg)

        if index < min_index:
            min_index = index
        if index > max_index:
            max_index = index

    if instruction.cargs:
        return qregs[min_index:]

    return qregs[min_index:max_index + 1]

def _get_gate_span ( qregs , instruction ) : min_index = len ( qregs ) max_index = 0 for qreg in instruction . qargs : index = qregs . index ( qreg ) if index < min_index : min_index = index if index > max_index : max_index = index if instruction . cargs : return qregs [ min_index : ] return qregs [ min_index : max_index + 1 ]


def circuit_to_instruction(circuit):
    """Build an ``Instruction`` object from a ``QuantumCircuit``.

    The instruction is anonymous (not tied to a named quantum register),
    and so can be inserted into another circuit. The instruction will
    have the same string name as the circuit.

    Args:
        circuit (QuantumCircuit): the input circuit.

    Return:
        Instruction: an instruction equivalent to the action of the
            input circuit. Upon decomposition, this instruction will
            yield the components comprising the original circuit.
    """
    instruction = Instruction(name=circuit.name,
                              num_qubits=sum([qreg.size for qreg in circuit.qregs]),
                              num_clbits=sum([creg.size for creg in circuit.cregs]),
                              params=[])
    instruction.control = None

    def find_bit_position(bit):
        """find the index of a given bit (Register, int) within
        a flat ordered list of bits of the circuit
        """
        if isinstance(bit[0], QuantumRegister):
            ordered_regs = circuit.qregs
        else:
            ordered_regs = circuit.cregs
        reg_index = ordered_regs.index(bit[0])
        return sum([reg.size for reg in ordered_regs[:reg_index]]) + bit[1]

    definition = circuit.data.copy()

    if instruction.num_qubits > 0:
        q = QuantumRegister(instruction.num_qubits, 'q')
    if instruction.num_clbits > 0:
        c = ClassicalRegister(instruction.num_clbits, 'c')

    definition = list(map(lambda x:
                          (x[0],
                           list(map(lambda y: (q, find_bit_position(y)), x[1])),
                           list(map(lambda y: (c, find_bit_position(y)), x[2]))), definition))
    instruction.definition = definition

    return instruction

def circuit_to_instruction ( circuit ) : instruction = Instruction ( name = circuit . name , num_qubits = sum ( [ qreg . size for qreg in circuit . qregs ] ) , num_clbits = sum ( [ creg . size for creg in circuit . cregs ] ) , params = [ ] ) instruction . control = None def find_bit_position ( bit ) : if isinstance ( bit [ 0 ] , QuantumRegister ) : ordered_regs = circuit . qregs else : ordered_regs = circuit . cregs reg_index = ordered_regs . index ( bit [ 0 ] ) return sum ( [ reg . size for reg in ordered_regs [ : reg_index ] ] ) + bit [ 1 ] definition = circuit . data . copy ( ) if instruction . num_qubits > 0 : q = QuantumRegister ( instruction . num_qubits , 'q' ) if instruction . num_clbits > 0 : c = ClassicalRegister ( instruction . num_clbits , 'c' ) definition = list ( map ( lambda x : ( x [ 0 ] , list ( map ( lambda y : ( q , find_bit_position ( y ) ) , x [ 1 ] ) ) , list ( map ( lambda y : ( c , find_bit_position ( y ) ) , x [ 2 ] ) ) ) , definition ) ) instruction . definition = definition return instruction

Build an Instruction object from a QuantumCircuit .


def run(self, dag):
        """
        Pick a convenient layout depending on the best matching
        qubit connectivity, and set the property `layout`.

        Args:
            dag (DAGCircuit): DAG to find layout for.

        Raises:
            TranspilerError: if dag wider than self.coupling_map
        """
        num_dag_qubits = sum([qreg.size for qreg in dag.qregs.values()])
        if num_dag_qubits > self.coupling_map.size():
            raise TranspilerError('Number of qubits greater than device.')
        best_sub = self._best_subset(num_dag_qubits)
        layout = Layout()
        map_iter = 0
        for qreg in dag.qregs.values():
            for i in range(qreg.size):
                layout[(qreg, i)] = int(best_sub[map_iter])
                map_iter += 1
        self.property_set['layout'] = layout

def
run
(
self
,
dag
)
:
num_dag_qubits
=
sum
(
[
qreg
.
size
for
qreg
in
dag
.
qregs
.
values
(
)
]
)
if
num_dag_qubits
>
self
.
coupling_map
.
size
(
)
:
raise
TranspilerError
(
'Number of qubits greater than device.'
)
best_sub
=
self
.
_best_subset
(
num_dag_qubits
)
layout
=
Layout
(
)
map_iter
=
0
for
qreg
in
dag
.
qregs
.
values
(
)
:
for
i
in
range
(
qreg
.
size
)
:
layout
[
(
qreg
,
i
)
]
=
int
(
best_sub
[
map_iter
]
)
map_iter
+=
1
self
.
property_set
[
'layout'
]
=
layout

Pick a convenient layout depending on the best matching qubit connectivity and set the property layout .


def _best_subset(self, n_qubits):
        """Computes the qubit mapping with the best connectivity.

        Args:
            n_qubits (int): Number of subset qubits to consider.

        Returns:
            ndarray: Array of qubits to use for best connectivity mapping.
        """
        if n_qubits == 1:
            return np.array([0])

        device_qubits = self.coupling_map.size()

        cmap = np.asarray(self.coupling_map.get_edges())
        data = np.ones_like(cmap[:, 0])
        sp_cmap = sp.coo_matrix((data, (cmap[:, 0], cmap[:, 1])),
                                shape=(device_qubits, device_qubits)).tocsr()
        best = 0
        best_map = None
        # do bfs with each node as starting point
        for k in range(sp_cmap.shape[0]):
            bfs = cs.breadth_first_order(sp_cmap, i_start=k, directed=False,
                                         return_predecessors=False)

            connection_count = 0
            sub_graph = []
            for i in range(n_qubits):
                node_idx = bfs[i]
                for j in range(sp_cmap.indptr[node_idx],
                               sp_cmap.indptr[node_idx + 1]):
                    node = sp_cmap.indices[j]
                    for counter in range(n_qubits):
                        if node == bfs[counter]:
                            connection_count += 1
                            sub_graph.append([node_idx, node])
                            break

            if connection_count > best:
                best = connection_count
                best_map = bfs[0:n_qubits]
                # Return a best mapping that has reduced bandwidth
                mapping = {}
                for edge in range(best_map.shape[0]):
                    mapping[best_map[edge]] = edge
                new_cmap = [[mapping[c[0]], mapping[c[1]]] for c in sub_graph]
                rows = [edge[0] for edge in new_cmap]
                cols = [edge[1] for edge in new_cmap]
                data = [1]*len(rows)
                sp_sub_graph = sp.coo_matrix((data, (rows, cols)),
                                             shape=(n_qubits, n_qubits)).tocsr()
                perm = cs.reverse_cuthill_mckee(sp_sub_graph)
                best_map = best_map[perm]
        return best_map

def _best_subset ( self , n_qubits ) : if n_qubits == 1 : return np . array ( [ 0 ] ) device_qubits = self . coupling_map . size ( ) cmap = np . asarray ( self . coupling_map . get_edges ( ) ) data = np . ones_like ( cmap [ : , 0 ] ) sp_cmap = sp . coo_matrix ( ( data , ( cmap [ : , 0 ] , cmap [ : , 1 ] ) ) , shape = ( device_qubits , device_qubits ) ) . tocsr ( ) best = 0 best_map = None for k in range ( sp_cmap . shape [ 0 ] ) : bfs = cs . breadth_first_order ( sp_cmap , i_start = k , directed = False , return_predecessors = False ) connection_count = 0 sub_graph = [ ] for i in range ( n_qubits ) : node_idx = bfs [ i ] for j in range ( sp_cmap . indptr [ node_idx ] , sp_cmap . indptr [ node_idx + 1 ] ) : node = sp_cmap . indices [ j ] for counter in range ( n_qubits ) : if node == bfs [ counter ] : connection_count += 1 sub_graph . append ( [ node_idx , node ] ) break if connection_count > best : best = connection_count best_map = bfs [ 0 : n_qubits ] mapping = { } for edge in range ( best_map . shape [ 0 ] ) : mapping [ best_map [ edge ] ] = edge new_cmap = [ [ mapping [ c [ 0 ] ] , mapping [ c [ 1 ] ] ] for c in sub_graph ] rows = [ edge [ 0 ] for edge in new_cmap ] cols = [ edge [ 1 ] for edge in new_cmap ] data = [ 1 ] * len ( rows ) sp_sub_graph = sp . coo_matrix ( ( data , ( rows , cols ) ) , shape = ( n_qubits , n_qubits ) ) . tocsr ( ) perm = cs . reverse_cuthill_mckee ( sp_sub_graph ) best_map = best_map [ perm ] return best_map

Computes the qubit mapping with the best connectivity .


def barrier(self, *qargs):
    """Apply barrier to circuit.
    If qargs is None, applies to all the qbits.
    Args is a list of QuantumRegister or single qubits.
    For QuantumRegister, applies barrier to all the qubits in that register."""
    qubits = []

    qargs = _convert_to_bits(qargs, [qbit for qreg in self.qregs for qbit in qreg])

    if not qargs:  # None
        for qreg in self.qregs:
            for j in range(qreg.size):
                qubits.append((qreg, j))

    for qarg in qargs:
        if isinstance(qarg, (QuantumRegister, list)):
            if isinstance(qarg, QuantumRegister):
                qubits.extend([(qarg, j) for j in range(qarg.size)])
            else:
                qubits.extend(qarg)
        else:
            qubits.append(qarg)

    return self.append(Barrier(len(qubits)), qubits, [])

def barrier ( self , * qargs ) : qubits = [ ] qargs = _convert_to_bits ( qargs , [ qbit for qreg in self . qregs for qbit in qreg ] ) if not qargs : for qreg in self . qregs : for j in range ( qreg . size ) : qubits . append ( ( qreg , j ) ) for qarg in qargs : if isinstance ( qarg , ( QuantumRegister , list ) ) : if isinstance ( qarg , QuantumRegister ) : qubits . extend ( [ ( qarg , j ) for j in range ( qarg . size ) ] ) else : qubits . extend ( qarg ) else : qubits . append ( qarg ) return self . append ( Barrier ( len ( qubits ) ) , qubits , [ ] )

Apply barrier to circuit . If qargs is None applies to all the qbits . Args is a list of QuantumRegister or single qubits . For QuantumRegister applies barrier to all the qubits in that register .


def average_data(counts, observable):
    """Compute the mean value of an diagonal observable.

    Takes in a diagonal observable in dictionary, list or matrix format and then
    calculates the sum_i value(i) P(i) where value(i) is the value of the
    observable for state i.

    Args:
        counts (dict): a dict of outcomes from an experiment
        observable (dict or matrix or list): The observable to be averaged over.
        As an example, ZZ on qubits can be given as:
        * dict: {"00": 1, "11": 1, "01": -1, "10": -1}
        * matrix: [[1, 0, 0, 0], [0, -1, 0, 0, ], [0, 0, -1, 0], [0, 0, 0, 1]]
        * matrix diagonal (list): [1, -1, -1, 1]

    Returns:
        Double: Average of the observable
    """
    if not isinstance(observable, dict):
        observable = make_dict_observable(observable)
    temp = 0
    tot = sum(counts.values())
    for key in counts:
        if key in observable:
            temp += counts[key] * observable[key] / tot
    return temp

def average_data ( counts , observable ) : if not isinstance ( observable , dict ) : observable = make_dict_observable ( observable ) temp = 0 tot = sum ( counts . values ( ) ) for key in counts : if key in observable : temp += counts [ key ] * observable [ key ] / tot return temp

Compute the mean value of an diagonal observable .


def _process_bit_id(self, node):
        """Process an Id or IndexedId node as a bit or register type.

        Return a list of tuples (Register,index).
        """
        # pylint: disable=inconsistent-return-statements
        reg = None
        if node.name in self.dag.qregs:
            reg = self.dag.qregs[node.name]
        elif node.name in self.dag.cregs:
            reg = self.dag.cregs[node.name]
        else:
            raise QiskitError("expected qreg or creg name:",
                              "line=%s" % node.line,
                              "file=%s" % node.file)

        if node.type == "indexed_id":
            # An indexed bit or qubit
            return [(reg, node.index)]
        elif node.type == "id":
            # A qubit or qreg or creg
            if not self.bit_stack[-1]:
                # Global scope
                return [(reg, j) for j in range(reg.size)]
            else:
                # local scope
                if node.name in self.bit_stack[-1]:
                    return [self.bit_stack[-1][node.name]]
                raise QiskitError("expected local bit name:",
                                  "line=%s" % node.line,
                                  "file=%s" % node.file)
        return None

def
_process_bit_id
(
self
,
node
)
:
reg
=
if
node
.
name
in
self
.
dag
.
qregs
:
reg
=
self
.
dag
.
qregs
[
node
.
name
]
elif
node
.
name
in
self
.
dag
.
cregs
:
reg
=
self
.
dag
.
cregs
[
node
.
name
]
else
:
raise
QiskitError
(
"expected qreg or creg name:"
,
"line=%s"
%
node
.
line
,
"file=%s"
%
node
.
file
)
if
node
.
type
==
"indexed_id"
:
return
[
(
reg
,
node
.
index
)
]
elif
node
.
type
==
"id"
:
if
not
self
.
bit_stack
[
1
]
:
return
[
(
reg
,
j
)
for
j
in
range
(
reg
.
size
)
]
else
:
if
node
.
name
in
self
.
bit_stack
[
1
]
:
return
[
self
.
bit_stack
[
1
]
[
node
.
name
]
]
raise
QiskitError
(
"expected local bit name:"
,
"line=%s"
%
node
.
line
,
"file=%s"
%
node
.
file
)
return

Process an Id or IndexedId node as a bit or register type .


def _process_custom_unitary(self, node):
        """Process a custom unitary node."""
        name = node.name
        if node.arguments is not None:
            args = self._process_node(node.arguments)
        else:
            args = []
        bits = [self._process_bit_id(node_element)
                for node_element in node.bitlist.children]
        if name in self.gates:
            gargs = self.gates[name]["args"]
            gbits = self.gates[name]["bits"]
            # Loop over register arguments, if any.
            maxidx = max(map(len, bits))
            for idx in range(maxidx):
                self.arg_stack.append({gargs[j]: args[j]
                                       for j in range(len(gargs))})
                # Only index into register arguments.
                element = [idx*x for x in
                           [len(bits[j]) > 1 for j in range(len(bits))]]
                self.bit_stack.append({gbits[j]: bits[j][element[j]]
                                       for j in range(len(gbits))})
                self._create_dag_op(name,
                                    [self.arg_stack[-1][s].sym() for s in gargs],
                                    [self.bit_stack[-1][s] for s in gbits])
                self.arg_stack.pop()
                self.bit_stack.pop()
        else:
            raise QiskitError("internal error undefined gate:",
                              "line=%s" % node.line, "file=%s" % node.file)

def
_process_custom_unitary
(
self
,
node
)
:
name
=
node
.
name
if
node
.
arguments
is
not
:
args
=
self
.
_process_node
(
node
.
arguments
)
else
:
args
=
[
]
bits
=
[
self
.
_process_bit_id
(
node_element
)
for
node_element
in
node
.
bitlist
.
children
]
if
name
in
self
.
gates
:
gargs
=
self
.
gates
[
name
]
[
"args"
]
gbits
=
self
.
gates
[
name
]
[
"bits"
]
maxidx
=
max
(
map
(
len
,
bits
)
)
for
idx
in
range
(
maxidx
)
:
self
.
arg_stack
.
append
(
{
gargs
[
j
]
:
args
[
j
]
for
j
in
range
(
len
(
gargs
)
)
}
)
element
=
[
idx
*
x
for
x
in
[
len
(
bits
[
j
]
)
>
1
for
j
in
range
(
len
(
bits
)
)
]
]
self
.
bit_stack
.
append
(
{
gbits
[
j
]
:
bits
[
j
]
[
element
[
j
]
]
for
j
in
range
(
len
(
gbits
)
)
}
)
self
.
_create_dag_op
(
name
,
[
self
.
arg_stack
[
1
]
[
s
]
.
sym
(
)
for
s
in
gargs
]
,
[
self
.
bit_stack
[
1
]
[
s
]
for
s
in
gbits
]
)
self
.
arg_stack
.
pop
(
)
self
.
bit_stack
.
pop
(
)
else
:
raise
QiskitError
(
"internal error undefined gate:"
,
"line=%s"
%
node
.
line
,
"file=%s"
%
node
.
file
)


def _process_gate(self, node, opaque=False):
        """Process a gate node.

        If opaque is True, process the node as an opaque gate node.
        """
        self.gates[node.name] = {}
        de_gate = self.gates[node.name]
        de_gate["print"] = True  # default
        de_gate["opaque"] = opaque
        de_gate["n_args"] = node.n_args()
        de_gate["n_bits"] = node.n_bits()
        if node.n_args() > 0:
            de_gate["args"] = [element.name for element in node.arguments.children]
        else:
            de_gate["args"] = []
        de_gate["bits"] = [c.name for c in node.bitlist.children]
        if opaque:
            de_gate["body"] = None
        else:
            de_gate["body"] = node.body

def _process_gate ( self , node , opaque = False ) : self . gates [ node . name ] = { } de_gate = self . gates [ node . name ] de_gate [ "print" ] = True de_gate [ "opaque" ] = opaque de_gate [ "n_args" ] = node . n_args ( ) de_gate [ "n_bits" ] = node . n_bits ( ) if node . n_args ( ) > 0 : de_gate [ "args" ] = [ element . name for element in node . arguments . children ] else : de_gate [ "args" ] = [ ] de_gate [ "bits" ] = [ c . name for c in node . bitlist . children ] if opaque : de_gate [ "body" ] = None else : de_gate [ "body" ] = node . body


def _process_cnot(self, node):
        """Process a CNOT gate node."""
        id0 = self._process_bit_id(node.children[0])
        id1 = self._process_bit_id(node.children[1])
        if not(len(id0) == len(id1) or len(id0) == 1 or len(id1) == 1):
            raise QiskitError("internal error: qreg size mismatch",
                              "line=%s" % node.line, "file=%s" % node.file)
        maxidx = max([len(id0), len(id1)])
        for idx in range(maxidx):
            if len(id0) > 1 and len(id1) > 1:
                self.dag.apply_operation_back(CXBase(), [id0[idx], id1[idx]], [], self.condition)
            elif len(id0) > 1:
                self.dag.apply_operation_back(CXBase(), [id0[idx], id1[0]], [], self.condition)
            else:
                self.dag.apply_operation_back(CXBase(), [id0[0], id1[idx]], [], self.condition)

def
_process_cnot
(
self
,
node
)
:
id0
=
self
.
_process_bit_id
(
node
.
children
[
0
]
)
id1
=
self
.
_process_bit_id
(
node
.
children
[
1
]
)
if
not
(
len
(
id0
)
==
len
(
id1
)
or
len
(
id0
)
==
1
or
len
(
id1
)
==
1
)
:
raise
QiskitError
(
"internal error: qreg size mismatch"
,
"line=%s"
%
node
.
line
,
"file=%s"
%
node
.
file
)
maxidx
=
max
(
[
len
(
id0
)
,
len
(
id1
)
]
)
for
idx
in
range
(
maxidx
)
:
if
len
(
id0
)
>
1
and
len
(
id1
)
>
1
:
self
.
dag
.
apply_operation_back
(
CXBase
(
)
,
[
id0
[
idx
]
,
id1
[
idx
]
]
,
[
]
,
self
.
condition
)
elif
len
(
id0
)
>
1
:
self
.
dag
.
apply_operation_back
(
CXBase
(
)
,
[
id0
[
idx
]
,
id1
[
0
]
]
,
[
]
,
self
.
condition
)
else
:
self
.
dag
.
apply_operation_back
(
CXBase
(
)
,
[
id0
[
0
]
,
id1
[
idx
]
]
,
[
]
,
self
.
condition
)


def _process_measure(self, node):
        """Process a measurement node."""
        id0 = self._process_bit_id(node.children[0])
        id1 = self._process_bit_id(node.children[1])
        if len(id0) != len(id1):
            raise QiskitError("internal error: reg size mismatch",
                              "line=%s" % node.line, "file=%s" % node.file)
        for idx, idy in zip(id0, id1):
            self.dag.apply_operation_back(Measure(), [idx], [idy], self.condition)

def
_process_measure
(
self
,
node
)
:
id0
=
self
.
_process_bit_id
(
node
.
children
[
0
]
)
id1
=
self
.
_process_bit_id
(
node
.
children
[
1
]
)
if
len
(
id0
)
!=
len
(
id1
)
:
raise
QiskitError
(
"internal error: reg size mismatch"
,
"line=%s"
%
node
.
line
,
"file=%s"
%
node
.
file
)
for
idx
,
idy
in
zip
(
id0
,
id1
)
:
self
.
dag
.
apply_operation_back
(
Measure
(
)
,
[
idx
]
,
[
idy
]
,
self
.
condition
)


def _process_if(self, node):
        """Process an if node."""
        creg_name = node.children[0].name
        creg = self.dag.cregs[creg_name]
        cval = node.children[1].value
        self.condition = (creg, cval)
        self._process_node(node.children[2])
        self.condition = None

def _process_if ( self , node ) : creg_name = node . children [ 0 ] . name creg = self . dag . cregs [ creg_name ] cval = node . children [ 1 ] . value self . condition = ( creg , cval ) self . _process_node ( node . children [ 2 ] ) self . condition = None


def _create_dag_op(self, name, params, qargs):
        """
        Create a DAG node out of a parsed AST op node.

        Args:
            name (str): operation name to apply to the dag.
            params (list): op parameters
            qargs (list(QuantumRegister, int)): qubits to attach to

        Raises:
            QiskitError: if encountering a non-basis opaque gate
        """
        if name == "u0":
            op_class = U0Gate
        elif name == "u1":
            op_class = U1Gate
        elif name == "u2":
            op_class = U2Gate
        elif name == "u3":
            op_class = U3Gate
        elif name == "x":
            op_class = XGate
        elif name == "y":
            op_class = YGate
        elif name == "z":
            op_class = ZGate
        elif name == "t":
            op_class = TGate
        elif name == "tdg":
            op_class = TdgGate
        elif name == "s":
            op_class = SGate
        elif name == "sdg":
            op_class = SdgGate
        elif name == "swap":
            op_class = SwapGate
        elif name == "rx":
            op_class = RXGate
        elif name == "ry":
            op_class = RYGate
        elif name == "rz":
            op_class = RZGate
        elif name == "rzz":
            op_class = RZZGate
        elif name == "id":
            op_class = IdGate
        elif name == "h":
            op_class = HGate
        elif name == "cx":
            op_class = CnotGate
        elif name == "cy":
            op_class = CyGate
        elif name == "cz":
            op_class = CzGate
        elif name == "ch":
            op_class = CHGate
        elif name == "crz":
            op_class = CrzGate
        elif name == "cu1":
            op_class = Cu1Gate
        elif name == "cu3":
            op_class = Cu3Gate
        elif name == "ccx":
            op_class = ToffoliGate
        elif name == "cswap":
            op_class = FredkinGate
        else:
            raise QiskitError("unknown operation for ast node name %s" % name)

        op = op_class(*params)

        self.dag.apply_operation_back(op, qargs, [], condition=self.condition)

Create a DAG node out of a parsed AST op node .


def ch_duration(self, *channels: List[Channel]) -> int:
        """Return duration of supplied channels.

        Args:
            *channels: Supplied channels
        """
        return self.timeslots.ch_duration(*channels)

def ch_duration ( self , * channels : List [ Channel ] ) -> int : return self . timeslots . ch_duration ( * channels )


def ch_start_time(self, *channels: List[Channel]) -> int:
        """Return minimum start time for supplied channels.

        Args:
            *channels: Supplied channels
        """
        return self.timeslots.ch_start_time(*channels)

def ch_start_time ( self , * channels : List [ Channel ] ) -> int : return self . timeslots . ch_start_time ( * channels )

Return minimum start time for supplied channels .


def ch_stop_time(self, *channels: List[Channel]) -> int:
        """Return maximum start time for supplied channels.

        Args:
            *channels: Supplied channels
        """
        return self.timeslots.ch_stop_time(*channels)

def ch_stop_time ( self , * channels : List [ Channel ] ) -> int : return self . timeslots . ch_stop_time ( * channels )

Return maximum start time for supplied channels .


def _instructions(self, time: int = 0) -> Iterable[Tuple[int, 'Instruction']]:
        """Iterable for flattening Schedule tree.

        Args:
            time: Shifted time due to parent

        Yields:
            Tuple[int, ScheduleComponent]: Tuple containing time `ScheduleComponent` starts
                at and the flattened `ScheduleComponent`.
        """
        for insert_time, child_sched in self.children:
            yield from child_sched._instructions(time + insert_time)

def _instructions ( self , time : int = 0 ) -> Iterable [ Tuple [ int , 'Instruction' ] ] : for insert_time , child_sched in self . children : yield from child_sched . _instructions ( time + insert_time )


def check_type(self, value, attr, data):
        """Validates a value against the correct type of the field.

        It calls ``_expected_types`` to get a list of valid types.

        Subclasses can do one of the following:

            1. They can override the ``valid_types`` property with a tuple with
            the expected types for this field.

            2. They can override the ``_expected_types`` method to return a
            tuple of expected types for the field.

            3. They can change ``check_type`` completely to customize
            validation.

        This method or the overrides must return the ``value`` parameter
        untouched.
        """
        expected_types = self._expected_types()
        if not isinstance(value, expected_types):
            raise self._not_expected_type(
                value, expected_types, fields=[self], field_names=attr, data=data)
        return value

def check_type ( self , value , attr , data ) : expected_types = self . _expected_types ( ) if not isinstance ( value , expected_types ) : raise self . _not_expected_type ( value , expected_types , fields = [ self ] , field_names = attr , data = data ) return value

Validates a value against the correct type of the field .


def dump_additional_data(self, valid_data, many, original_data):
        """Include unknown fields after dumping.

        Unknown fields are added with no processing at all.

        Args:
            valid_data (dict or list): data collected and returned by ``dump()``.
            many (bool): if True, data and original_data are a list.
            original_data (object or list): object passed to ``dump()`` in the
                first place.

        Returns:
            dict: the same ``valid_data`` extended with the unknown attributes.

        Inspired by https://github.com/marshmallow-code/marshmallow/pull/595.
        """
        if many:
            for i, _ in enumerate(valid_data):
                additional_keys = set(original_data[i].__dict__) - set(valid_data[i])
                for key in additional_keys:
                    valid_data[i][key] = getattr(original_data[i], key)
        else:
            additional_keys = set(original_data.__dict__) - set(valid_data)
            for key in additional_keys:
                valid_data[key] = getattr(original_data, key)

        return valid_data

def dump_additional_data ( self , valid_data , many , original_data ) : if many : for i , _ in enumerate ( valid_data ) : additional_keys = set ( original_data [ i ] . __dict__ ) - set ( valid_data [ i ] ) for key in additional_keys : valid_data [ i ] [ key ] = getattr ( original_data [ i ] , key ) else : additional_keys = set ( original_data . __dict__ ) - set ( valid_data ) for key in additional_keys : valid_data [ key ] = getattr ( original_data , key ) return valid_data


def load_additional_data(self, valid_data, many, original_data):
        """Include unknown fields after load.

        Unknown fields are added with no processing at all.

        Args:
            valid_data (dict or list): validated data returned by ``load()``.
            many (bool): if True, data and original_data are a list.
            original_data (dict or list): data passed to ``load()`` in the
                first place.

        Returns:
            dict: the same ``valid_data`` extended with the unknown attributes.

        Inspired by https://github.com/marshmallow-code/marshmallow/pull/595.
        """
        if many:
            for i, _ in enumerate(valid_data):
                additional_keys = set(original_data[i]) - set(valid_data[i])
                for key in additional_keys:
                    valid_data[i][key] = original_data[i][key]
        else:
            additional_keys = set(original_data) - set(valid_data)
            for key in additional_keys:
                valid_data[key] = original_data[key]

        return valid_data

def load_additional_data ( self , valid_data , many , original_data ) : if many : for i , _ in enumerate ( valid_data ) : additional_keys = set ( original_data [ i ] ) - set ( valid_data [ i ] ) for key in additional_keys : valid_data [ i ] [ key ] = original_data [ i ] [ key ] else : additional_keys = set ( original_data ) - set ( valid_data ) for key in additional_keys : valid_data [ key ] = original_data [ key ] return valid_data


def _create_validation_schema(schema_cls):
        """Create a patched Schema for validating models.

        Model validation is not part of Marshmallow. Schemas have a ``validate``
        method but this delegates execution on ``load`` and discards the result.
        Similarly, ``load`` will call ``_deserialize`` on every field in the
        schema.

        This function patches the ``_deserialize`` instance method of each
        field to make it call a custom defined method ``check_type``
        provided by Qiskit in the different fields at
        ``qiskit.validation.fields``.

        Returns:
            BaseSchema: a copy of the original Schema, overriding the
                ``_deserialize()`` call of its fields.
        """
        validation_schema = schema_cls()
        for _, field in validation_schema.fields.items():
            if isinstance(field, ModelTypeValidator):
                validate_function = field.__class__.check_type
                field._deserialize = MethodType(validate_function, field)

        return validation_schema

def _create_validation_schema ( schema_cls ) : validation_schema = schema_cls ( ) for _ , field in validation_schema . fields . items ( ) : if isinstance ( field , ModelTypeValidator ) : validate_function = field . __class__ . check_type field . _deserialize = MethodType ( validate_function , field ) return validation_schema

Create a patched Schema for validating models .


def _validate(instance):
        """Validate the internal representation of the instance."""
        try:
            _ = instance.schema.validate(instance.to_dict())
        except ValidationError as ex:
            raise ModelValidationError(
                ex.messages, ex.field_names, ex.fields, ex.data, **ex.kwargs)

def _validate ( instance ) : try : _ = instance . schema . validate ( instance . to_dict ( ) ) except ValidationError as ex : raise ModelValidationError ( ex . messages , ex . field_names , ex . fields , ex . data , ** ex . kwargs )

Validate the internal representation of the instance .


def _validate_after_init(init_method):
        """Add validation after instantiation."""

        @wraps(init_method)
        def _decorated(self, **kwargs):
            try:
                _ = self.shallow_schema.validate(kwargs)
            except ValidationError as ex:
                raise ModelValidationError(
                    ex.messages, ex.field_names, ex.fields, ex.data, **ex.kwargs) from None

            init_method(self, **kwargs)

        return _decorated

def _validate_after_init ( init_method ) : @ wraps ( init_method ) def _decorated ( self , ** kwargs ) : try : _ = self . shallow_schema . validate ( kwargs ) except ValidationError as ex : raise ModelValidationError ( ex . messages , ex . field_names , ex . fields , ex . data , ** ex . kwargs ) from None init_method ( self , ** kwargs ) return _decorated


def to_dict(self):
        """Serialize the model into a Python dict of simple types.

        Note that this method requires that the model is bound with
        ``@bind_schema``.
        """
        try:
            data, _ = self.schema.dump(self)
        except ValidationError as ex:
            raise ModelValidationError(
                ex.messages, ex.field_names, ex.fields, ex.data, **ex.kwargs) from None

        return data

def to_dict ( self ) : try : data , _ = self . schema . dump ( self ) except ValidationError as ex : raise ModelValidationError ( ex . messages , ex . field_names , ex . fields , ex . data , ** ex . kwargs ) from None return data

Serialize the model into a Python dict of simple types .


def from_dict(cls, dict_):
        """Deserialize a dict of simple types into an instance of this class.

        Note that this method requires that the model is bound with
        ``@bind_schema``.
        """
        try:
            data, _ = cls.schema.load(dict_)
        except ValidationError as ex:
            raise ModelValidationError(
                ex.messages, ex.field_names, ex.fields, ex.data, **ex.kwargs) from None

        return data

def from_dict ( cls , dict_ ) : try : data , _ = cls . schema . load ( dict_ ) except ValidationError as ex : raise ModelValidationError ( ex . messages , ex . field_names , ex . fields , ex . data , ** ex . kwargs ) from None return data

Deserialize a dict of simple types into an instance of this class .


def qft(circ, q, n):
    """n-qubit QFT on q in circ."""
    for j in range(n):
        for k in range(j):
            circ.cu1(math.pi / float(2**(j - k)), q[j], q[k])
        circ.h(q[j])

def qft ( circ , q , n ) : for j in range ( n ) : for k in range ( j ) : circ . cu1 ( math . pi / float ( 2 ** ( j - k ) ) , q [ j ] , q [ k ] ) circ . h ( q [ j ] )


def __partial_trace_vec(vec, trace_systems, dimensions, reverse=True):
    """
    Partial trace over subsystems of multi-partite vector.

    Args:
        vec (vector_like): complex vector N
        trace_systems (list(int)): a list of subsystems (starting from 0) to
                                  trace over.
        dimensions (list(int)): a list of the dimensions of the subsystems.
                                If this is not set it will assume all
                                subsystems are qubits.
        reverse (bool): ordering of systems in operator.
            If True system-0 is the right most system in tensor product.
            If False system-0 is the left most system in tensor product.

    Returns:
        ndarray: A density matrix with the appropriate subsystems traced over.
    """

    # trace sys positions
    if reverse:
        dimensions = dimensions[::-1]
        trace_systems = len(dimensions) - 1 - np.array(trace_systems)

    rho = vec.reshape(dimensions)
    rho = np.tensordot(rho, rho.conj(), axes=(trace_systems, trace_systems))
    d = int(np.sqrt(np.product(rho.shape)))

    return rho.reshape(d, d)

def __partial_trace_vec ( vec , trace_systems , dimensions , reverse = True ) : if reverse : dimensions = dimensions [ : : - 1 ] trace_systems = len ( dimensions ) - 1 - np . array ( trace_systems ) rho = vec . reshape ( dimensions ) rho = np . tensordot ( rho , rho . conj ( ) , axes = ( trace_systems , trace_systems ) ) d = int ( np . sqrt ( np . product ( rho . shape ) ) ) return rho . reshape ( d , d )

Partial trace over subsystems of multi - partite vector .


def vectorize(density_matrix, method='col'):
    """Flatten an operator to a vector in a specified basis.

    Args:
        density_matrix (ndarray): a density matrix.
        method (str): the method of vectorization. Allowed values are
            - 'col' (default) flattens to column-major vector.
            - 'row' flattens to row-major vector.
            - 'pauli'flattens in the n-qubit Pauli basis.
            - 'pauli-weights': flattens in the n-qubit Pauli basis ordered by
               weight.

    Returns:
        ndarray: the resulting vector.
    Raises:
        Exception: if input state is not a n-qubit state
    """
    density_matrix = np.array(density_matrix)
    if method == 'col':
        return density_matrix.flatten(order='F')
    elif method == 'row':
        return density_matrix.flatten(order='C')
    elif method in ['pauli', 'pauli_weights']:
        num = int(np.log2(len(density_matrix)))  # number of qubits
        if len(density_matrix) != 2**num:
            raise Exception('Input state must be n-qubit state')
        if method == 'pauli_weights':
            pgroup = pauli_group(num, case='weight')
        else:
            pgroup = pauli_group(num, case='tensor')
        vals = [np.trace(np.dot(p.to_matrix(), density_matrix))
                for p in pgroup]
        return np.array(vals)
    return None

def
vectorize
(
density_matrix
,
method
=
'col'
)
:
density_matrix
=
np
.
array
(
density_matrix
)
if
method
==
'col'
:
return
density_matrix
.
flatten
(
order
=
'F'
)
elif
method
==
'row'
:
return
density_matrix
.
flatten
(
order
=
'C'
)
elif
method
in
[
'pauli'
,
'pauli_weights'
]
:
num
=
int
(
np
.
log2
(
len
(
density_matrix
)
)
)
if
len
(
density_matrix
)
!=
2
**
num
:
raise
Exception
(
'Input state must be n-qubit state'
)
if
method
==
'pauli_weights'
:
pgroup
=
pauli_group
(
num
,
case
=
'weight'
)
else
:
pgroup
=
pauli_group
(
num
,
case
=
'tensor'
)
vals
=
[
np
.
trace
(
np
.
dot
(
p
.
to_matrix
(
)
,
density_matrix
)
)
for
p
in
pgroup
]
return
np
.
array
(
vals
)
return

Flatten an operator to a vector in a specified basis .


def devectorize(vectorized_mat, method='col'):
    """Devectorize a vectorized square matrix.

    Args:
        vectorized_mat (ndarray): a vectorized density matrix.
        method (str): the method of devectorization. Allowed values are
            - 'col' (default): flattens to column-major vector.
            - 'row': flattens to row-major vector.
            - 'pauli': flattens in the n-qubit Pauli basis.
            - 'pauli-weights': flattens in the n-qubit Pauli basis ordered by
               weight.

    Returns:
        ndarray: the resulting matrix.
    Raises:
        Exception: if input state is not a n-qubit state
    """
    vectorized_mat = np.array(vectorized_mat)
    dimension = int(np.sqrt(vectorized_mat.size))
    if len(vectorized_mat) != dimension * dimension:
        raise Exception('Input is not a vectorized square matrix')

    if method == 'col':
        return vectorized_mat.reshape(dimension, dimension, order='F')
    elif method == 'row':
        return vectorized_mat.reshape(dimension, dimension, order='C')
    elif method in ['pauli', 'pauli_weights']:
        num_qubits = int(np.log2(dimension))  # number of qubits
        if dimension != 2 ** num_qubits:
            raise Exception('Input state must be n-qubit state')
        if method == 'pauli_weights':
            pgroup = pauli_group(num_qubits, case='weight')
        else:
            pgroup = pauli_group(num_qubits, case='tensor')
        pbasis = np.array([p.to_matrix() for p in pgroup]) / 2 ** num_qubits
        return np.tensordot(vectorized_mat, pbasis, axes=1)
    return None

Devectorize a vectorized square matrix .


def choi_to_rauli(choi, order=1):
    """
    Convert a Choi-matrix to a Pauli-basis superoperator.

    Note that this function assumes that the Choi-matrix
    is defined in the standard column-stacking convention
    and is normalized to have trace 1. For a channel E this
    is defined as: choi = (I \\otimes E)(bell_state).

    The resulting 'rauli' R acts on input states as
    |rho_out>_p = R.|rho_in>_p
    where |rho> = vectorize(rho, method='pauli') for order=1
    and |rho> = vectorize(rho, method='pauli_weights') for order=0.

    Args:
        choi (matrix): the input Choi-matrix.
        order (int): ordering of the Pauli group vector.
            order=1 (default) is standard lexicographic ordering.
                Eg: [II, IX, IY, IZ, XI, XX, XY,...]
            order=0 is ordered by weights.
                Eg. [II, IX, IY, IZ, XI, XY, XZ, XX, XY,...]

    Returns:
        np.array: A superoperator in the Pauli basis.
    """
    if order == 0:
        order = 'weight'
    elif order == 1:
        order = 'tensor'

    # get number of qubits'
    num_qubits = int(np.log2(np.sqrt(len(choi))))
    pgp = pauli_group(num_qubits, case=order)
    rauli = []
    for i in pgp:
        for j in pgp:
            pauliop = np.kron(j.to_matrix().T, i.to_matrix())
            rauli += [np.trace(np.dot(choi, pauliop))]
    return np.array(rauli).reshape(4 ** num_qubits, 4 ** num_qubits)

def choi_to_rauli ( choi , order = 1 ) : if order == 0 : order = 'weight' elif order == 1 : order = 'tensor' num_qubits = int ( np . log2 ( np . sqrt ( len ( choi ) ) ) ) pgp = pauli_group ( num_qubits , case = order ) rauli = [ ] for i in pgp : for j in pgp : pauliop = np . kron ( j . to_matrix ( ) . T , i . to_matrix ( ) ) rauli += [ np . trace ( np . dot ( choi , pauliop ) ) ] return np . array ( rauli ) . reshape ( 4 ** num_qubits , 4 ** num_qubits )

Convert a Choi - matrix to a Pauli - basis superoperator .


def chop(array, epsilon=1e-10):
    """
    Truncate small values of a complex array.

    Args:
        array (array_like): array to truncte small values.
        epsilon (float): threshold.

    Returns:
        np.array: A new operator with small values set to zero.
    """
    ret = np.array(array)

    if np.isrealobj(ret):
        ret[abs(ret) < epsilon] = 0.0
    else:
        ret.real[abs(ret.real) < epsilon] = 0.0
        ret.imag[abs(ret.imag) < epsilon] = 0.0
    return ret

def chop ( array , epsilon = 1e-10 ) : ret = np . array ( array ) if np . isrealobj ( ret ) : ret [ abs ( ret ) < epsilon ] = 0.0 else : ret . real [ abs ( ret . real ) < epsilon ] = 0.0 ret . imag [ abs ( ret . imag ) < epsilon ] = 0.0 return ret

Truncate small values of a complex array .


def outer(vector1, vector2=None):
    """
    Construct the outer product of two vectors.

    The second vector argument is optional, if absent the projector
    of the first vector will be returned.

    Args:
        vector1 (ndarray): the first vector.
        vector2 (ndarray): the (optional) second vector.

    Returns:
        np.array: The matrix |v1><v2|.

    """
    if vector2 is None:
        vector2 = np.array(vector1).conj()
    else:
        vector2 = np.array(vector2).conj()
    return np.outer(vector1, vector2)

def outer ( vector1 , vector2 = None ) : if vector2 is None : vector2 = np . array ( vector1 ) . conj ( ) else : vector2 = np . array ( vector2 ) . conj ( ) return np . outer ( vector1 , vector2 )

Construct the outer product of two vectors .


def concurrence(state):
    """Calculate the concurrence.

    Args:
        state (np.array): a quantum state (1x4 array) or a density matrix (4x4
                          array)
    Returns:
        float: concurrence.
    Raises:
        Exception: if attempted on more than two qubits.
    """
    rho = np.array(state)
    if rho.ndim == 1:
        rho = outer(state)
    if len(state) != 4:
        raise Exception("Concurrence is only defined for more than two qubits")

    YY = np.fliplr(np.diag([-1, 1, 1, -1]))
    A = rho.dot(YY).dot(rho.conj()).dot(YY)
    w = la.eigh(A, eigvals_only=True)
    w = np.sqrt(np.maximum(w, 0))
    return max(0.0, w[-1] - np.sum(w[0:-1]))


def shannon_entropy(pvec, base=2):
    """
    Compute the Shannon entropy of a probability vector.

    The shannon entropy of a probability vector pv is defined as
    $H(pv) = - \\sum_j pv[j] log_b (pv[j])$ where $0 log_b 0 = 0$.

    Args:
        pvec (array_like): a probability vector.
        base (int): the base of the logarith

    Returns:
        float: The Shannon entropy H(pvec).
    """
    # pylint: disable=missing-docstring
    if base == 2:
        def logfn(x):
            return - x * np.log2(x)
    elif base == np.e:
        def logfn(x):
            return - x * np.log(x)
    else:
        def logfn(x):
            return -x * np.log(x) / np.log(base)

    h = 0.
    for x in pvec:
        if 0 < x < 1:
            h += logfn(x)
    return h

def shannon_entropy ( pvec , base = 2 ) : if base == 2 : def logfn ( x ) : return - x * np . log2 ( x ) elif base == np . e : def logfn ( x ) : return - x * np . log ( x ) else : def logfn ( x ) : return - x * np . log ( x ) / np . log ( base ) h = 0. for x in pvec : if 0 < x < 1 : h += logfn ( x ) return h

Compute the Shannon entropy of a probability vector .


def entropy(state):
    """
    Compute the von-Neumann entropy of a quantum state.

    Args:
        state (array_like): a density matrix or state vector.

    Returns:
        float: The von-Neumann entropy S(rho).
    """

    rho = np.array(state)
    if rho.ndim == 1:
        return 0
    evals = np.maximum(np.linalg.eigvalsh(state), 0.)
    return shannon_entropy(evals, base=np.e)

def entropy ( state ) : rho = np . array ( state ) if rho . ndim == 1 : return 0 evals = np . maximum ( np . linalg . eigvalsh ( state ) , 0. ) return shannon_entropy ( evals , base = np . e )

Compute the von - Neumann entropy of a quantum state .


def mutual_information(state, d0, d1=None):
    """
    Compute the mutual information of a bipartite state.

    Args:
        state (array_like): a bipartite state-vector or density-matrix.
        d0 (int): dimension of the first subsystem.
        d1 (int or None): dimension of the second subsystem.

    Returns:
        float: The mutual information S(rho_A) + S(rho_B) - S(rho_AB).
    """
    if d1 is None:
        d1 = int(len(state) / d0)
    mi = entropy(partial_trace(state, [0], dimensions=[d0, d1]))
    mi += entropy(partial_trace(state, [1], dimensions=[d0, d1]))
    mi -= entropy(state)
    return mi

def mutual_information ( state , d0 , d1 = None ) : if d1 is None : d1 = int ( len ( state ) / d0 ) mi = entropy ( partial_trace ( state , [ 0 ] , dimensions = [ d0 , d1 ] ) ) mi += entropy ( partial_trace ( state , [ 1 ] , dimensions = [ d0 , d1 ] ) ) mi -= entropy ( state ) return mi

Compute the mutual information of a bipartite state .


def entanglement_of_formation(state, d0, d1=None):
    """
    Compute the entanglement of formation of quantum state.

    The input quantum state must be either a bipartite state vector, or a
    2-qubit density matrix.

    Args:
        state (array_like): (N) array_like or (4,4) array_like, a
            bipartite quantum state.
        d0 (int): the dimension of the first subsystem.
        d1 (int or None): the dimension of the second subsystem.

    Returns:
        float: The entanglement of formation.
    """
    state = np.array(state)

    if d1 is None:
        d1 = int(len(state) / d0)

    if state.ndim == 2 and len(state) == 4 and d0 == 2 and d1 == 2:
        return __eof_qubit(state)
    elif state.ndim == 1:
        # trace out largest dimension
        if d0 < d1:
            tr = [1]
        else:
            tr = [0]
        state = partial_trace(state, tr, dimensions=[d0, d1])
        return entropy(state)
    else:
        print('Input must be a state-vector or 2-qubit density matrix.')
    return None

Compute the entanglement of formation of quantum state .


def __eof_qubit(rho):
    """
    Compute the Entanglement of Formation of a 2-qubit density matrix.

    Args:
        rho ((array_like): (4,4) array_like, input density matrix.

    Returns:
        float: The entanglement of formation.
    """
    c = concurrence(rho)
    c = 0.5 + 0.5 * np.sqrt(1 - c * c)
    return shannon_entropy([c, 1 - c])

def __eof_qubit ( rho ) : c = concurrence ( rho ) c = 0.5 + 0.5 * np . sqrt ( 1 - c * c ) return shannon_entropy ( [ c , 1 - c ] )

Compute the Entanglement of Formation of a 2 - qubit density matrix .


def flatten(schedule: ScheduleComponent, name: str = None) -> Schedule:
    """Create a flattened schedule.

    Args:
        schedule: Schedules to flatten
        name: Name of the new schedule. Defaults to first element of `schedules`
    """
    if name is None:
        name = schedule.name

    return Schedule(*schedule.instructions, name=name)

def flatten ( schedule : ScheduleComponent , name : str = None ) -> Schedule : if name is None : name = schedule . name return Schedule ( * schedule . instructions , name = name )


def shift(schedule: ScheduleComponent, time: int, name: str = None) -> Schedule:
    """Return schedule shifted by `time`.

    Args:
        schedule: The schedule to shift
        time: The time to shift by
        name: Name of shifted schedule. Defaults to name of `schedule`
    """
    if name is None:
        name = schedule.name
    return union((time, schedule), name=name)

def shift ( schedule : ScheduleComponent , time : int , name : str = None ) -> Schedule : if name is None : name = schedule . name return union ( ( time , schedule ) , name = name )


def insert(parent: ScheduleComponent, time: int, child: ScheduleComponent,
           name: str = None) -> Schedule:
    """Return a new schedule with the `child` schedule inserted into the `parent` at `start_time`.

    Args:
        parent: Schedule to be inserted into
        time: Time to be inserted defined with respect to `parent`
        child: Schedule to insert
        name: Name of the new schedule. Defaults to name of parent
    """
    return union(parent, (time, child), name=name)

def insert ( parent : ScheduleComponent , time : int , child : ScheduleComponent , name : str = None ) -> Schedule : return union ( parent , ( time , child ) , name = name )

Return a new schedule with the child schedule inserted into the parent at start_time .


def append(parent: ScheduleComponent, child: ScheduleComponent,
           name: str = None) -> Schedule:
    r"""Return a new schedule with by appending `child` to `parent` at
       the last time of the `parent` schedule's channels
       over the intersection of the parent and child schedule's channels.

       $t = \textrm{max}({x.stop\_time |x \in parent.channels \cap child.channels})$

    Args:
        parent: The schedule to be inserted into
        child: The schedule to insert
        name: Name of the new schedule. Defaults to name of parent
    """
    common_channels = set(parent.channels) & set(child.channels)
    insertion_time = parent.ch_stop_time(*common_channels)
    return insert(parent, insertion_time, child, name=name)

def append ( parent : ScheduleComponent , child : ScheduleComponent , name : str = None ) -> Schedule : r common_channels = set ( parent . channels ) & set ( child . channels ) insertion_time = parent . ch_stop_time ( * common_channels ) return insert ( parent , insertion_time , child , name = name )

r Return a new schedule with by appending child to parent at the last time of the parent schedule s channels over the intersection of the parent and child schedule s channels .


def u3(self, theta, phi, lam, q):
    """Apply u3 to q."""
    return self.append(U3Gate(theta, phi, lam), [q], [])

def u3 ( self , theta , phi , lam , q ) : return self . append ( U3Gate ( theta , phi , lam ) , [ q ] , [ ] )


def status(self):
        """Return backend status.

        Returns:
            BackendStatus: the status of the backend.
        """
        return BackendStatus(backend_name=self.name(),
                             backend_version=__version__,
                             operational=True,
                             pending_jobs=0,
                             status_msg='')

def status ( self ) : return BackendStatus ( backend_name = self . name ( ) , backend_version = __version__ , operational = True , pending_jobs = 0 , status_msg = '' )


def start(self, iterations):
        """Start the progress bar.

        Parameters:
            iterations (int): Number of iterations.
        """
        self.touched = True
        self.iter = int(iterations)
        self.t_start = time.time()

def start ( self , iterations ) : self . touched = True self . iter = int ( iterations ) self . t_start = time . time ( )


def time_remaining_est(self, completed_iter):
        """Estimate the remaining time left.

        Parameters:
            completed_iter (int): Number of iterations completed.

        Returns:
            est_time: Estimated time remaining.
        """
        if completed_iter:
            t_r_est = (time.time() - self.t_start) / \
                completed_iter*(self.iter-completed_iter)
        else:
            t_r_est = 0
        date_time = datetime.datetime(1, 1, 1) + datetime.timedelta(seconds=t_r_est)
        time_string = "%02d:%02d:%02d:%02d" % \
            (date_time.day - 1, date_time.hour, date_time.minute, date_time.second)

        return time_string

def time_remaining_est ( self , completed_iter ) : if completed_iter : t_r_est = ( time . time ( ) - self . t_start ) / completed_iter * ( self . iter - completed_iter ) else : t_r_est = 0 date_time = datetime . datetime ( 1 , 1 , 1 ) + datetime . timedelta ( seconds = t_r_est ) time_string = "%02d:%02d:%02d:%02d" % ( date_time . day - 1 , date_time . hour , date_time . minute , date_time . second ) return time_string


def disassemble(qobj):
    """Dissasemble a qobj and return the circuits, run_config, and user header

    Args:
        qobj (Qobj): The input qobj object to dissasemble
    Returns:
        circuits (list): A list of quantum circuits
        run_config (dict): The dist of the run config
        user_qobj_header (dict): The dict of any user headers in the qobj

    """
    run_config = qobj.config.to_dict()
    user_qobj_header = qobj.header.to_dict()
    circuits = _experiments_to_circuits(qobj)

    return circuits, run_config, user_qobj_header

def disassemble ( qobj ) : run_config = qobj . config . to_dict ( ) user_qobj_header = qobj . header . to_dict ( ) circuits = _experiments_to_circuits ( qobj ) return circuits , run_config , user_qobj_header

Dissasemble a qobj and return the circuits run_config and user header


def hamming_distance(str1, str2):
    """Calculate the Hamming distance between two bit strings

    Args:
        str1 (str): First string.
        str2 (str): Second string.
    Returns:
        int: Distance between strings.
    Raises:
        VisualizationError: Strings not same length
    """
    if len(str1) != len(str2):
        raise VisualizationError('Strings not same length.')
    return sum(s1 != s2 for s1, s2 in zip(str1, str2))

def
hamming_distance
(
str1
,
str2
)
:
if
len
(
str1
)
!=
len
(
str2
)
:
raise
VisualizationError
(
'Strings not same length.'
)
return
sum
(
s1
!=
s2
for
s1
,
s2
in
zip
(
str1
,
str2
)
)


def quaternion_from_axis_rotation(angle, axis):
    """Return quaternion for rotation about given axis.

    Args:
        angle (float): Angle in radians.
        axis (str): Axis for rotation

    Returns:
        Quaternion: Quaternion for axis rotation.

    Raises:
        ValueError: Invalid input axis.
    """
    out = np.zeros(4, dtype=float)
    if axis == 'x':
        out[1] = 1
    elif axis == 'y':
        out[2] = 1
    elif axis == 'z':
        out[3] = 1
    else:
        raise ValueError('Invalid axis input.')
    out *= math.sin(angle/2.0)
    out[0] = math.cos(angle/2.0)
    return Quaternion(out)

def
quaternion_from_axis_rotation
(
angle
,
axis
)
:
out
=
np
.
zeros
(
4
,
dtype
=
float
)
if
axis
==
'x'
:
out
[
1
]
=
1
elif
axis
==
'y'
:
out
[
2
]
=
1
elif
axis
==
'z'
:
out
[
3
]
=
1
else
:
raise
ValueError
(
'Invalid axis input.'
)
out
*=
math
.
sin
(
angle
/
2.0
)
out
[
0
]
=
math
.
cos
(
angle
/
2.0
)
return
Quaternion
(
out
)

Return quaternion for rotation about given axis .


def quaternion_from_euler(angles, order='yzy'):
    """Generate a quaternion from a set of Euler angles.

    Args:
        angles (array_like): Array of Euler angles.
        order (str): Order of Euler rotations.  'yzy' is default.

    Returns:
        Quaternion: Quaternion representation of Euler rotation.
    """
    angles = np.asarray(angles, dtype=float)
    quat = quaternion_from_axis_rotation(angles[0], order[0])\
        * (quaternion_from_axis_rotation(angles[1], order[1])
           * quaternion_from_axis_rotation(angles[2], order[2]))
    quat.normalize(inplace=True)
    return quat

def quaternion_from_euler ( angles , order = 'yzy' ) : angles = np . asarray ( angles , dtype = float ) quat = quaternion_from_axis_rotation ( angles [ 0 ] , order [ 0 ] ) * ( quaternion_from_axis_rotation ( angles [ 1 ] , order [ 1 ] ) * quaternion_from_axis_rotation ( angles [ 2 ] , order [ 2 ] ) ) quat . normalize ( inplace = True ) return quat

Generate a quaternion from a set of Euler angles .


def normalize(self, inplace=False):
        """Normalizes a Quaternion to unit length
        so that it represents a valid rotation.

        Args:
            inplace (bool): Do an inplace normalization.

        Returns:
            Quaternion: Normalized quaternion.
        """
        if inplace:
            nrm = self.norm()
            self.data /= nrm
            return None
        nrm = self.norm()
        data_copy = np.array(self.data, copy=True)
        data_copy /= nrm
        return Quaternion(data_copy)

def normalize ( self , inplace = False ) : if inplace : nrm = self . norm ( ) self . data /= nrm return None nrm = self . norm ( ) data_copy = np . array ( self . data , copy = True ) data_copy /= nrm return Quaternion ( data_copy )

Normalizes a Quaternion to unit length so that it represents a valid rotation .


def to_matrix(self):
        """Converts a unit-length quaternion to a rotation matrix.

        Returns:
            ndarray: Rotation matrix.
        """
        w, x, y, z = self.normalize().data  # pylint: disable=C0103
        mat = np.array([
            [1-2*y**2-2*z**2, 2*x*y-2*z*w, 2*x*z+2*y*w],
            [2*x*y+2*z*w, 1-2*x**2-2*z**2, 2*y*z-2*x*w],
            [2*x*z-2*y*w, 2*y*z+2*x*w, 1-2*x**2-2*y**2]
        ], dtype=float)
        return mat

Converts a unit - length quaternion to a rotation matrix .


def to_zyz(self):
        """Converts a unit-length quaternion to a sequence
        of ZYZ Euler angles.

        Returns:
            ndarray: Array of Euler angles.
        """
        mat = self.to_matrix()
        euler = np.zeros(3, dtype=float)
        if mat[2, 2] < 1:
            if mat[2, 2] > -1:
                euler[0] = math.atan2(mat[1, 2], mat[0, 2])
                euler[1] = math.acos(mat[2, 2])
                euler[2] = math.atan2(mat[2, 1], -mat[2, 0])
            else:
                euler[0] = -math.atan2(mat[1, 0], mat[1, 1])
                euler[1] = np.pi
        else:
            euler[0] = math.atan2(mat[1, 0], mat[1, 1])
        return euler

def to_zyz ( self ) : mat = self . to_matrix ( ) euler = np . zeros ( 3 , dtype = float ) if mat [ 2 , 2 ] < 1 : if mat [ 2 , 2 ] > - 1 : euler [ 0 ] = math . atan2 ( mat [ 1 , 2 ] , mat [ 0 , 2 ] ) euler [ 1 ] = math . acos ( mat [ 2 , 2 ] ) euler [ 2 ] = math . atan2 ( mat [ 2 , 1 ] , - mat [ 2 , 0 ] ) else : euler [ 0 ] = - math . atan2 ( mat [ 1 , 0 ] , mat [ 1 , 1 ] ) euler [ 1 ] = np . pi else : euler [ 0 ] = math . atan2 ( mat [ 1 , 0 ] , mat [ 1 , 1 ] ) return euler

Converts a unit - length quaternion to a sequence of ZYZ Euler angles .


def process_data(data, number_to_keep):
    """ Prepare received data for representation.

        Args:
            data (dict): values to represent (ex. {'001' : 130})
            number_to_keep (int): number of elements to show individually.

        Returns:
            dict: processed data to show.
    """

    result = dict()

    if number_to_keep != 0:
        data_temp = dict(Counter(data).most_common(number_to_keep))
        data_temp['rest'] = sum(data.values()) - sum(data_temp.values())
        data = data_temp

    labels = data
    values = np.array([data[key] for key in labels], dtype=float)
    pvalues = values / sum(values)
    for position, label in enumerate(labels):
        result[label] = round(pvalues[position], 5)

    return result

def process_data ( data , number_to_keep ) : result = dict ( ) if number_to_keep != 0 : data_temp = dict ( Counter ( data ) . most_common ( number_to_keep ) ) data_temp [ 'rest' ] = sum ( data . values ( ) ) - sum ( data_temp . values ( ) ) data = data_temp labels = data values = np . array ( [ data [ key ] for key in labels ] , dtype = float ) pvalues = values / sum ( values ) for position , label in enumerate ( labels ) : result [ label ] = round ( pvalues [ position ] , 5 ) return result

Prepare received data for representation .


def iplot_histogram(data, figsize=None, number_to_keep=None,
                    sort='asc', legend=None):
    """ Create a histogram representation.

        Graphical representation of the input array using a vertical bars
        style graph.

        Args:
            data (list or dict):  This is either a list of dicts or a single
                dict containing the values to represent (ex. {'001' : 130})
            figsize (tuple): Figure size in pixels.
            number_to_keep (int): The number of terms to plot and
                rest is made into a single bar called other values
            sort (string): Could be 'asc' or 'desc'
            legend (list): A list of strings to use for labels of the data.
                The number of entries must match the length of data.
        Raises:
            VisualizationError: When legend is provided and the length doesn't
                match the input data.
    """

    # HTML
    html_template = Template("""

    """)

    # JavaScript
    javascript_template = Template("""

    """)

    # Process data and execute
    div_number = str(time.time())
    div_number = re.sub('[.]', '', div_number)

    # set default figure size if none provided
    if figsize is None:
        figsize = (7, 5)

    options = {'number_to_keep': 0 if number_to_keep is None else number_to_keep,
               'sort': sort,
               'show_legend': 0,
               'width': int(figsize[0]),
               'height': int(figsize[1])}
    if legend:
        options['show_legend'] = 1

    data_to_plot = []
    if isinstance(data, dict):
        data = [data]

    if legend and len(legend) != len(data):
        raise VisualizationError("Length of legendL (%s) doesn't match number "
                                 "of input executions: %s" %
                                 (len(legend), len(data)))

    for item, execution in enumerate(data):
        exec_data = process_data(execution, options['number_to_keep'])
        out_dict = {'data': exec_data}
        if legend:
            out_dict['name'] = legend[item]
        data_to_plot.append(out_dict)

    html = html_template.substitute({
        'divNumber': div_number
    })

    javascript = javascript_template.substitute({
        'divNumber': div_number,
        'executions': data_to_plot,
        'options': options
    })

    display(HTML(html + javascript))


def check_type(self, value, attr, data):
        """Customize check_type for handling containers."""
        # Check the type in the standard way first, in order to fail quickly
        # in case of invalid values.
        root_value = super(InstructionParameter, self).check_type(
            value, attr, data)

        if is_collection(value):
            _ = [super(InstructionParameter, self).check_type(item, attr, data)
                 for item in value]

        return root_value

def check_type ( self , value , attr , data ) : root_value = super ( InstructionParameter , self ) . check_type ( value , attr , data ) if is_collection ( value ) : _ = [ super ( InstructionParameter , self ) . check_type ( item , attr , data ) for item in value ] return root_value

Customize check_type for handling containers .


def check_range(self, j):
        """Check that j is a valid index into self."""
        if isinstance(j, int):
            if j < 0 or j >= self.size:
                raise QiskitIndexError("register index out of range")
            elif isinstance(j, slice):
                if j.start < 0 or j.stop >= self.size or (j.step is not None and
                                                          j.step <= 0):
                    raise QiskitIndexError("register index slice out of range")

def
check_range
(
self
,
j
)
:
if
isinstance
(
j
,
int
)
:
if
j
<
0
or
j
>=
self
.
size
:
raise
QiskitIndexError
(
"register index out of range"
)
elif
isinstance
(
j
,
slice
)
:
if
j
.
start
<
0
or
j
.
stop
>=
self
.
size
or
(
j
.
step
is
not
and
j
.
step
<=
0
)
:
raise
QiskitIndexError
(
"register index slice out of range"
)

Check that j is a valid index into self .


def is_square_matrix(mat):
    """Test if an array is a square matrix."""
    mat = np.array(mat)
    if mat.ndim != 2:
        return False
    shape = mat.shape
    return shape[0] == shape[1]

def is_square_matrix ( mat ) : mat = np . array ( mat ) if mat . ndim != 2 : return False shape = mat . shape return shape [ 0 ] == shape [ 1 ]


def is_diagonal_matrix(mat, rtol=RTOL_DEFAULT, atol=ATOL_DEFAULT):
    """Test if an array is a diagonal matrix"""
    if atol is None:
        atol = ATOL_DEFAULT
    if rtol is None:
        rtol = RTOL_DEFAULT
    mat = np.array(mat)
    if mat.ndim != 2:
        return False
    return np.allclose(mat, np.diag(np.diagonal(mat)), rtol=rtol, atol=atol)

def is_diagonal_matrix ( mat , rtol = RTOL_DEFAULT , atol = ATOL_DEFAULT ) : if atol is None : atol = ATOL_DEFAULT if rtol is None : rtol = RTOL_DEFAULT mat = np . array ( mat ) if mat . ndim != 2 : return False return np . allclose ( mat , np . diag ( np . diagonal ( mat ) ) , rtol = rtol , atol = atol )


def is_symmetric_matrix(op, rtol=RTOL_DEFAULT, atol=ATOL_DEFAULT):
    """Test if an array is a symmetrix matrix"""
    if atol is None:
        atol = ATOL_DEFAULT
    if rtol is None:
        rtol = RTOL_DEFAULT
    mat = np.array(op)
    if mat.ndim != 2:
        return False
    return np.allclose(mat, mat.T, rtol=rtol, atol=atol)

def is_symmetric_matrix ( op , rtol = RTOL_DEFAULT , atol = ATOL_DEFAULT ) : if atol is None : atol = ATOL_DEFAULT if rtol is None : rtol = RTOL_DEFAULT mat = np . array ( op ) if mat . ndim != 2 : return False return np . allclose ( mat , mat . T , rtol = rtol , atol = atol )


def is_hermitian_matrix(mat, rtol=RTOL_DEFAULT, atol=ATOL_DEFAULT):
    """Test if an array is a Hermitian matrix"""
    if atol is None:
        atol = ATOL_DEFAULT
    if rtol is None:
        rtol = RTOL_DEFAULT
    mat = np.array(mat)
    if mat.ndim != 2:
        return False
    return np.allclose(mat, np.conj(mat.T), rtol=rtol, atol=atol)

def is_hermitian_matrix ( mat , rtol = RTOL_DEFAULT , atol = ATOL_DEFAULT ) : if atol is None : atol = ATOL_DEFAULT if rtol is None : rtol = RTOL_DEFAULT mat = np . array ( mat ) if mat . ndim != 2 : return False return np . allclose ( mat , np . conj ( mat . T ) , rtol = rtol , atol = atol )


def is_positive_semidefinite_matrix(mat, rtol=RTOL_DEFAULT, atol=ATOL_DEFAULT):
    """Test if a matrix is positive semidefinite"""
    if atol is None:
        atol = ATOL_DEFAULT
    if rtol is None:
        rtol = RTOL_DEFAULT
    if not is_hermitian_matrix(mat, rtol=rtol, atol=atol):
        return False
    # Check eigenvalues are all positive
    vals = np.linalg.eigvalsh(mat)
    for v in vals:
        if v < -atol:
            return False
    return True

def is_positive_semidefinite_matrix ( mat , rtol = RTOL_DEFAULT , atol = ATOL_DEFAULT ) : if atol is None : atol = ATOL_DEFAULT if rtol is None : rtol = RTOL_DEFAULT if not is_hermitian_matrix ( mat , rtol = rtol , atol = atol ) : return False vals = np . linalg . eigvalsh ( mat ) for v in vals : if v < - atol : return False return True


def is_identity_matrix(mat,
                       ignore_phase=False,
                       rtol=RTOL_DEFAULT,
                       atol=ATOL_DEFAULT):
    """Test if an array is an identity matrix."""
    if atol is None:
        atol = ATOL_DEFAULT
    if rtol is None:
        rtol = RTOL_DEFAULT
    mat = np.array(mat)
    if mat.ndim != 2:
        return False
    if ignore_phase:
        # If the matrix is equal to an identity up to a phase, we can
        # remove the phase by multiplying each entry by the complex
        # conjugate of the phase of the [0, 0] entry.
        theta = np.angle(mat[0, 0])
        mat = np.exp(-1j * theta) * mat
    # Check if square identity
    iden = np.eye(len(mat))
    return np.allclose(mat, iden, rtol=rtol, atol=atol)

def is_identity_matrix ( mat , ignore_phase = False , rtol = RTOL_DEFAULT , atol = ATOL_DEFAULT ) : if atol is None : atol = ATOL_DEFAULT if rtol is None : rtol = RTOL_DEFAULT mat = np . array ( mat ) if mat . ndim != 2 : return False if ignore_phase : theta = np . angle ( mat [ 0 , 0 ] ) mat = np . exp ( - 1j * theta ) * mat iden = np . eye ( len ( mat ) ) return np . allclose ( mat , iden , rtol = rtol , atol = atol )

Test if an array is an identity matrix .


def is_unitary_matrix(mat, rtol=RTOL_DEFAULT, atol=ATOL_DEFAULT):
    """Test if an array is a unitary matrix."""
    if atol is None:
        atol = ATOL_DEFAULT
    if rtol is None:
        rtol = RTOL_DEFAULT
    mat = np.array(mat)
    # Compute A^dagger.A and see if it is identity matrix
    mat = np.conj(mat.T).dot(mat)
    return is_identity_matrix(mat, ignore_phase=False, rtol=rtol, atol=atol)

def is_unitary_matrix ( mat , rtol = RTOL_DEFAULT , atol = ATOL_DEFAULT ) : if atol is None : atol = ATOL_DEFAULT if rtol is None : rtol = RTOL_DEFAULT mat = np . array ( mat ) mat = np . conj ( mat . T ) . dot ( mat ) return is_identity_matrix ( mat , ignore_phase = False , rtol = rtol , atol = atol )


def _to_choi(rep, data, input_dim, output_dim):
    """Transform a QuantumChannel to the Choi representation."""
    if rep == 'Choi':
        return data
    if rep == 'Operator':
        return _from_operator('Choi', data, input_dim, output_dim)
    if rep == 'SuperOp':
        return _superop_to_choi(data, input_dim, output_dim)
    if rep == 'Kraus':
        return _kraus_to_choi(data, input_dim, output_dim)
    if rep == 'Chi':
        return _chi_to_choi(data, input_dim, output_dim)
    if rep == 'PTM':
        data = _ptm_to_superop(data, input_dim, output_dim)
        return _superop_to_choi(data, input_dim, output_dim)
    if rep == 'Stinespring':
        return _stinespring_to_choi(data, input_dim, output_dim)
    raise QiskitError('Invalid QuantumChannel {}'.format(rep))

def
_to_choi
(
rep
,
data
,
input_dim
,
output_dim
)
:
if
rep
==
'Choi'
:
return
data
if
rep
==
'Operator'
:
return
_from_operator
(
'Choi'
,
data
,
input_dim
,
output_dim
)
if
rep
==
'SuperOp'
:
return
_superop_to_choi
(
data
,
input_dim
,
output_dim
)
if
rep
==
'Kraus'
:
return
_kraus_to_choi
(
data
,
input_dim
,
output_dim
)
if
rep
==
'Chi'
:
return
_chi_to_choi
(
data
,
input_dim
,
output_dim
)
if
rep
==
'PTM'
:
data
=
_ptm_to_superop
(
data
,
input_dim
,
output_dim
)
return
_superop_to_choi
(
data
,
input_dim
,
output_dim
)
if
rep
==
'Stinespring'
:
return
_stinespring_to_choi
(
data
,
input_dim
,
output_dim
)
raise
QiskitError
(
'Invalid QuantumChannel {}'
.
format
(
rep
)
)

Transform a QuantumChannel to the Choi representation .


def _to_superop(rep, data, input_dim, output_dim):
    """Transform a QuantumChannel to the SuperOp representation."""
    if rep == 'SuperOp':
        return data
    if rep == 'Operator':
        return _from_operator('SuperOp', data, input_dim, output_dim)
    if rep == 'Choi':
        return _choi_to_superop(data, input_dim, output_dim)
    if rep == 'Kraus':
        return _kraus_to_superop(data, input_dim, output_dim)
    if rep == 'Chi':
        data = _chi_to_choi(data, input_dim, output_dim)
        return _choi_to_superop(data, input_dim, output_dim)
    if rep == 'PTM':
        return _ptm_to_superop(data, input_dim, output_dim)
    if rep == 'Stinespring':
        return _stinespring_to_superop(data, input_dim, output_dim)
    raise QiskitError('Invalid QuantumChannel {}'.format(rep))

def
_to_superop
(
rep
,
data
,
input_dim
,
output_dim
)
:
if
rep
==
'SuperOp'
:
return
data
if
rep
==
'Operator'
:
return
_from_operator
(
'SuperOp'
,
data
,
input_dim
,
output_dim
)
if
rep
==
'Choi'
:
return
_choi_to_superop
(
data
,
input_dim
,
output_dim
)
if
rep
==
'Kraus'
:
return
_kraus_to_superop
(
data
,
input_dim
,
output_dim
)
if
rep
==
'Chi'
:
data
=
_chi_to_choi
(
data
,
input_dim
,
output_dim
)
return
_choi_to_superop
(
data
,
input_dim
,
output_dim
)
if
rep
==
'PTM'
:
return
_ptm_to_superop
(
data
,
input_dim
,
output_dim
)
if
rep
==
'Stinespring'
:
return
_stinespring_to_superop
(
data
,
input_dim
,
output_dim
)
raise
QiskitError
(
'Invalid QuantumChannel {}'
.
format
(
rep
)
)

Transform a QuantumChannel to the SuperOp representation .


def _to_kraus(rep, data, input_dim, output_dim):
    """Transform a QuantumChannel to the Kraus representation."""
    if rep == 'Kraus':
        return data
    if rep == 'Stinespring':
        return _stinespring_to_kraus(data, input_dim, output_dim)
    if rep == 'Operator':
        return _from_operator('Kraus', data, input_dim, output_dim)
    # Convert via Choi and Kraus
    if rep != 'Choi':
        data = _to_choi(rep, data, input_dim, output_dim)
    return _choi_to_kraus(data, input_dim, output_dim)

def _to_kraus ( rep , data , input_dim , output_dim ) : if rep == 'Kraus' : return data if rep == 'Stinespring' : return _stinespring_to_kraus ( data , input_dim , output_dim ) if rep == 'Operator' : return _from_operator ( 'Kraus' , data , input_dim , output_dim ) if rep != 'Choi' : data = _to_choi ( rep , data , input_dim , output_dim ) return _choi_to_kraus ( data , input_dim , output_dim )

Transform a QuantumChannel to the Kraus representation .


def _to_chi(rep, data, input_dim, output_dim):
    """Transform a QuantumChannel to the Chi representation."""
    if rep == 'Chi':
        return data
    # Check valid n-qubit input
    _check_nqubit_dim(input_dim, output_dim)
    if rep == 'Operator':
        return _from_operator('Chi', data, input_dim, output_dim)
    # Convert via Choi representation
    if rep != 'Choi':
        data = _to_choi(rep, data, input_dim, output_dim)
    return _choi_to_chi(data, input_dim, output_dim)

def _to_chi ( rep , data , input_dim , output_dim ) : if rep == 'Chi' : return data _check_nqubit_dim ( input_dim , output_dim ) if rep == 'Operator' : return _from_operator ( 'Chi' , data , input_dim , output_dim ) if rep != 'Choi' : data = _to_choi ( rep , data , input_dim , output_dim ) return _choi_to_chi ( data , input_dim , output_dim )

Transform a QuantumChannel to the Chi representation .


def _to_ptm(rep, data, input_dim, output_dim):
    """Transform a QuantumChannel to the PTM representation."""
    if rep == 'PTM':
        return data
    # Check valid n-qubit input
    _check_nqubit_dim(input_dim, output_dim)
    if rep == 'Operator':
        return _from_operator('PTM', data, input_dim, output_dim)
    # Convert via Superoperator representation
    if rep != 'SuperOp':
        data = _to_superop(rep, data, input_dim, output_dim)
    return _superop_to_ptm(data, input_dim, output_dim)

def _to_ptm ( rep , data , input_dim , output_dim ) : if rep == 'PTM' : return data _check_nqubit_dim ( input_dim , output_dim ) if rep == 'Operator' : return _from_operator ( 'PTM' , data , input_dim , output_dim ) if rep != 'SuperOp' : data = _to_superop ( rep , data , input_dim , output_dim ) return _superop_to_ptm ( data , input_dim , output_dim )

Transform a QuantumChannel to the PTM representation .


def _to_stinespring(rep, data, input_dim, output_dim):
    """Transform a QuantumChannel to the Stinespring representation."""
    if rep == 'Stinespring':
        return data
    if rep == 'Operator':
        return _from_operator('Stinespring', data, input_dim, output_dim)
    # Convert via Superoperator representation
    if rep != 'Kraus':
        data = _to_kraus(rep, data, input_dim, output_dim)
    return _kraus_to_stinespring(data, input_dim, output_dim)

def _to_stinespring ( rep , data , input_dim , output_dim ) : if rep == 'Stinespring' : return data if rep == 'Operator' : return _from_operator ( 'Stinespring' , data , input_dim , output_dim ) if rep != 'Kraus' : data = _to_kraus ( rep , data , input_dim , output_dim ) return _kraus_to_stinespring ( data , input_dim , output_dim )

Transform a QuantumChannel to the Stinespring representation .


def _to_operator(rep, data, input_dim, output_dim):
    """Transform a QuantumChannel to the Operator representation."""
    if rep == 'Operator':
        return data
    if rep == 'Stinespring':
        return _stinespring_to_operator(data, input_dim, output_dim)
    # Convert via Kraus representation
    if rep != 'Kraus':
        data = _to_kraus(rep, data, input_dim, output_dim)
    return _kraus_to_operator(data, input_dim, output_dim)

def _to_operator ( rep , data , input_dim , output_dim ) : if rep == 'Operator' : return data if rep == 'Stinespring' : return _stinespring_to_operator ( data , input_dim , output_dim ) if rep != 'Kraus' : data = _to_kraus ( rep , data , input_dim , output_dim ) return _kraus_to_operator ( data , input_dim , output_dim )

Transform a QuantumChannel to the Operator representation .


def _from_operator(rep, data, input_dim, output_dim):
    """Transform Operator representation to other representation."""
    if rep == 'Operator':
        return data
    if rep == 'SuperOp':
        return np.kron(np.conj(data), data)
    if rep == 'Choi':
        vec = np.ravel(data, order='F')
        return np.outer(vec, np.conj(vec))
    if rep == 'Kraus':
        return ([data], None)
    if rep == 'Stinespring':
        return (data, None)
    if rep == 'Chi':
        _check_nqubit_dim(input_dim, output_dim)
        data = _from_operator('Choi', data, input_dim, output_dim)
        return _choi_to_chi(data, input_dim, output_dim)
    if rep == 'PTM':
        _check_nqubit_dim(input_dim, output_dim)
        data = _from_operator('SuperOp', data, input_dim, output_dim)
        return _superop_to_ptm(data, input_dim, output_dim)
    raise QiskitError('Invalid QuantumChannel {}'.format(rep))

def
_from_operator
(
rep
,
data
,
input_dim
,
output_dim
)
:
if
rep
==
'Operator'
:
return
data
if
rep
==
'SuperOp'
:
return
np
.
kron
(
np
.
conj
(
data
)
,
data
)
if
rep
==
'Choi'
:
vec
=
np
.
ravel
(
data
,
order
=
'F'
)
return
np
.
outer
(
vec
,
np
.
conj
(
vec
)
)
if
rep
==
'Kraus'
:
return
(
[
data
]
,
)
if
rep
==
'Stinespring'
:
return
(
data
,
)
if
rep
==
'Chi'
:
_check_nqubit_dim
(
input_dim
,
output_dim
)
data
=
_from_operator
(
'Choi'
,
data
,
input_dim
,
output_dim
)
return
_choi_to_chi
(
data
,
input_dim
,
output_dim
)
if
rep
==
'PTM'
:
_check_nqubit_dim
(
input_dim
,
output_dim
)
data
=
_from_operator
(
'SuperOp'
,
data
,
input_dim
,
output_dim
)
return
_superop_to_ptm
(
data
,
input_dim
,
output_dim
)
raise
QiskitError
(
'Invalid QuantumChannel {}'
.
format
(
rep
)
)

Transform Operator representation to other representation .


def _stinespring_to_operator(data, input_dim, output_dim):
    """Transform Stinespring representation to Operator representation."""
    trace_dim = data[0].shape[0] // output_dim
    if data[1] is not None or trace_dim != 1:
        raise QiskitError(
            'Channel cannot be converted to Operator representation')
    return data[0]

Transform Stinespring representation to Operator representation .


def _superop_to_choi(data, input_dim, output_dim):
    """Transform SuperOp representation to Choi representation."""
    shape = (output_dim, output_dim, input_dim, input_dim)
    return _reshuffle(data, shape)

def _superop_to_choi ( data , input_dim , output_dim ) : shape = ( output_dim , output_dim , input_dim , input_dim ) return _reshuffle ( data , shape )

Transform SuperOp representation to Choi representation .


def _choi_to_superop(data, input_dim, output_dim):
    """Transform Choi to SuperOp representation."""
    shape = (input_dim, output_dim, input_dim, output_dim)
    return _reshuffle(data, shape)

def _choi_to_superop ( data , input_dim , output_dim ) : shape = ( input_dim , output_dim , input_dim , output_dim ) return _reshuffle ( data , shape )

Transform Choi to SuperOp representation .


def _kraus_to_choi(data, input_dim, output_dim):
    """Transform Kraus representation to Choi representation."""
    choi = 0
    kraus_l, kraus_r = data
    if kraus_r is None:
        for i in kraus_l:
            vec = i.ravel(order='F')
            choi += np.outer(vec, vec.conj())
    else:
        for i, j in zip(kraus_l, kraus_r):
            choi += np.outer(i.ravel(order='F'), j.ravel(order='F').conj())
    return choi

def _kraus_to_choi ( data , input_dim , output_dim ) : choi = 0 kraus_l , kraus_r = data if kraus_r is None : for i in kraus_l : vec = i . ravel ( order = 'F' ) choi += np . outer ( vec , vec . conj ( ) ) else : for i , j in zip ( kraus_l , kraus_r ) : choi += np . outer ( i . ravel ( order = 'F' ) , j . ravel ( order = 'F' ) . conj ( ) ) return choi

Transform Kraus representation to Choi representation .


def _choi_to_kraus(data, input_dim, output_dim, atol=ATOL_DEFAULT):
    """Transform Choi representation to Kraus representation."""
    # Check if hermitian matrix
    if is_hermitian_matrix(data, atol=atol):
        # Get eigen-decomposition of Choi-matrix
        w, v = la.eigh(data)
        # Check eigenvaleus are non-negative
        if len(w[w < -atol]) == 0:
            # CP-map Kraus representation
            kraus = []
            for val, vec in zip(w, v.T):
                if abs(val) > atol:
                    k = np.sqrt(val) * vec.reshape(
                        (output_dim, input_dim), order='F')
                    kraus.append(k)
            # If we are converting a zero matrix, we need to return a Kraus set
            # with a single zero-element Kraus matrix
            if not kraus:
                kraus.append(np.zeros((output_dim, input_dim), dtype=complex))
            return (kraus, None)
    # Non-CP-map generalized Kraus representation
    mat_u, svals, mat_vh = la.svd(data)
    kraus_l = []
    kraus_r = []
    for val, vec_l, vec_r in zip(svals, mat_u.T, mat_vh.conj()):
        kraus_l.append(
            np.sqrt(val) * vec_l.reshape((output_dim, input_dim), order='F'))
        kraus_r.append(
            np.sqrt(val) * vec_r.reshape((output_dim, input_dim), order='F'))
    return (kraus_l, kraus_r)

def _choi_to_kraus ( data , input_dim , output_dim , atol = ATOL_DEFAULT ) : if is_hermitian_matrix ( data , atol = atol ) : w , v = la . eigh ( data ) if len ( w [ w < - atol ] ) == 0 : kraus = [ ] for val , vec in zip ( w , v . T ) : if abs ( val ) > atol : k = np . sqrt ( val ) * vec . reshape ( ( output_dim , input_dim ) , order = 'F' ) kraus . append ( k ) if not kraus : kraus . append ( np . zeros ( ( output_dim , input_dim ) , dtype = complex ) ) return ( kraus , None ) mat_u , svals , mat_vh = la . svd ( data ) kraus_l = [ ] kraus_r = [ ] for val , vec_l , vec_r in zip ( svals , mat_u . T , mat_vh . conj ( ) ) : kraus_l . append ( np . sqrt ( val ) * vec_l . reshape ( ( output_dim , input_dim ) , order = 'F' ) ) kraus_r . append ( np . sqrt ( val ) * vec_r . reshape ( ( output_dim , input_dim ) , order = 'F' ) ) return ( kraus_l , kraus_r )

Transform Choi representation to Kraus representation .


def _stinespring_to_kraus(data, input_dim, output_dim):
    """Transform Stinespring representation to Kraus representation."""
    kraus_pair = []
    for stine in data:
        if stine is None:
            kraus_pair.append(None)
        else:
            trace_dim = stine.shape[0] // output_dim
            iden = np.eye(output_dim)
            kraus = []
            for j in range(trace_dim):
                vec = np.zeros(trace_dim)
                vec[j] = 1
                kraus.append(np.kron(iden, vec[None, :]).dot(stine))
            kraus_pair.append(kraus)
    return tuple(kraus_pair)

def _stinespring_to_kraus ( data , input_dim , output_dim ) : kraus_pair = [ ] for stine in data : if stine is None : kraus_pair . append ( None ) else : trace_dim = stine . shape [ 0 ] // output_dim iden = np . eye ( output_dim ) kraus = [ ] for j in range ( trace_dim ) : vec = np . zeros ( trace_dim ) vec [ j ] = 1 kraus . append ( np . kron ( iden , vec [ None , : ] ) . dot ( stine ) ) kraus_pair . append ( kraus ) return tuple ( kraus_pair )

Transform Stinespring representation to Kraus representation .


def _stinespring_to_choi(data, input_dim, output_dim):
    """Transform Stinespring representation to Choi representation."""
    trace_dim = data[0].shape[0] // output_dim
    stine_l = np.reshape(data[0], (output_dim, trace_dim, input_dim))
    if data[1] is None:
        stine_r = stine_l
    else:
        stine_r = np.reshape(data[1], (output_dim, trace_dim, input_dim))
    return np.reshape(
        np.einsum('iAj,kAl->jilk', stine_l, stine_r.conj()),
        2 * [input_dim * output_dim])

def _stinespring_to_choi ( data , input_dim , output_dim ) : trace_dim = data [ 0 ] . shape [ 0 ] // output_dim stine_l = np . reshape ( data [ 0 ] , ( output_dim , trace_dim , input_dim ) ) if data [ 1 ] is None : stine_r = stine_l else : stine_r = np . reshape ( data [ 1 ] , ( output_dim , trace_dim , input_dim ) ) return np . reshape ( np . einsum ( 'iAj,kAl->jilk' , stine_l , stine_r . conj ( ) ) , 2 * [ input_dim * output_dim ] )

Transform Stinespring representation to Choi representation .


def _kraus_to_stinespring(data, input_dim, output_dim):
    """Transform Kraus representation to Stinespring representation."""
    stine_pair = [None, None]
    for i, kraus in enumerate(data):
        if kraus is not None:
            num_kraus = len(kraus)
            stine = np.zeros((output_dim * num_kraus, input_dim),
                             dtype=complex)
            for j, mat in enumerate(kraus):
                vec = np.zeros(num_kraus)
                vec[j] = 1
                stine += np.kron(mat, vec[:, None])
            stine_pair[i] = stine
    return tuple(stine_pair)

def _kraus_to_stinespring ( data , input_dim , output_dim ) : stine_pair = [ None , None ] for i , kraus in enumerate ( data ) : if kraus is not None : num_kraus = len ( kraus ) stine = np . zeros ( ( output_dim * num_kraus , input_dim ) , dtype = complex ) for j , mat in enumerate ( kraus ) : vec = np . zeros ( num_kraus ) vec [ j ] = 1 stine += np . kron ( mat , vec [ : , None ] ) stine_pair [ i ] = stine return tuple ( stine_pair )

Transform Kraus representation to Stinespring representation .


def _kraus_to_superop(data, input_dim, output_dim):
    """Transform Kraus representation to SuperOp representation."""
    kraus_l, kraus_r = data
    superop = 0
    if kraus_r is None:
        for i in kraus_l:
            superop += np.kron(np.conj(i), i)
    else:
        for i, j in zip(kraus_l, kraus_r):
            superop += np.kron(np.conj(j), i)
    return superop

def _kraus_to_superop ( data , input_dim , output_dim ) : kraus_l , kraus_r = data superop = 0 if kraus_r is None : for i in kraus_l : superop += np . kron ( np . conj ( i ) , i ) else : for i , j in zip ( kraus_l , kraus_r ) : superop += np . kron ( np . conj ( j ) , i ) return superop

Transform Kraus representation to SuperOp representation .


def _chi_to_choi(data, input_dim, output_dim):
    """Transform Chi representation to a Choi representation."""
    num_qubits = int(np.log2(input_dim))
    return _transform_from_pauli(data, num_qubits)

def _chi_to_choi ( data , input_dim , output_dim ) : num_qubits = int ( np . log2 ( input_dim ) ) return _transform_from_pauli ( data , num_qubits )

Transform Chi representation to a Choi representation .


def _choi_to_chi(data, input_dim, output_dim):
    """Transform Choi representation to the Chi representation."""
    num_qubits = int(np.log2(input_dim))
    return _transform_to_pauli(data, num_qubits)

def _choi_to_chi ( data , input_dim , output_dim ) : num_qubits = int ( np . log2 ( input_dim ) ) return _transform_to_pauli ( data , num_qubits )

Transform Choi representation to the Chi representation .


def _reravel(mat1, mat2, shape1, shape2):
    """Reravel two bipartite matrices."""
    # Reshuffle indicies
    left_dims = shape1[:2] + shape2[:2]
    right_dims = shape1[2:] + shape2[2:]
    tensor_shape = left_dims + right_dims
    final_shape = (np.product(left_dims), np.product(right_dims))
    # Tensor product matrices
    data = np.kron(mat1, mat2)
    data = np.reshape(
        np.transpose(np.reshape(data, tensor_shape), (0, 2, 1, 3, 4, 6, 5, 7)),
        final_shape)
    return data

def _reravel ( mat1 , mat2 , shape1 , shape2 ) : left_dims = shape1 [ : 2 ] + shape2 [ : 2 ] right_dims = shape1 [ 2 : ] + shape2 [ 2 : ] tensor_shape = left_dims + right_dims final_shape = ( np . product ( left_dims ) , np . product ( right_dims ) ) data = np . kron ( mat1 , mat2 ) data = np . reshape ( np . transpose ( np . reshape ( data , tensor_shape ) , ( 0 , 2 , 1 , 3 , 4 , 6 , 5 , 7 ) ) , final_shape ) return data


def _transform_from_pauli(data, num_qubits):
    """Change of basis of bipartite matrix represenation."""
    # Change basis: sum_{i=0}^3 =|\sigma_i>><i|
    basis_mat = np.array(
        [[1, 0, 0, 1], [0, 1, 1j, 0], [0, 1, -1j, 0], [1, 0j, 0, -1]],
        dtype=complex)
    # Note that we manually renormalized after change of basis
    # to avoid rounding errors from square-roots of 2.
    cob = basis_mat
    for _ in range(num_qubits - 1):
        dim = int(np.sqrt(len(cob)))
        cob = np.reshape(
            np.transpose(
                np.reshape(
                    np.kron(basis_mat, cob), (2, 2, dim, dim, 4, dim * dim)),
                (0, 2, 1, 3, 4, 5)), (4 * dim * dim, 4 * dim * dim))
    return np.dot(np.dot(cob, data), cob.conj().T) / 2**num_qubits

def _transform_from_pauli ( data , num_qubits ) : basis_mat = np . array ( [ [ 1 , 0 , 0 , 1 ] , [ 0 , 1 , 1j , 0 ] , [ 0 , 1 , - 1j , 0 ] , [ 1 , 0j , 0 , - 1 ] ] , dtype = complex ) cob = basis_mat for _ in range ( num_qubits - 1 ) : dim = int ( np . sqrt ( len ( cob ) ) ) cob = np . reshape ( np . transpose ( np . reshape ( np . kron ( basis_mat , cob ) , ( 2 , 2 , dim , dim , 4 , dim * dim ) ) , ( 0 , 2 , 1 , 3 , 4 , 5 ) ) , ( 4 * dim * dim , 4 * dim * dim ) ) return np . dot ( np . dot ( cob , data ) , cob . conj ( ) . T ) / 2 ** num_qubits

Change of basis of bipartite matrix represenation .


def _check_nqubit_dim(input_dim, output_dim):
    """Return true if dims correspond to an n-qubit channel."""
    if input_dim != output_dim:
        raise QiskitError(
            'Not an n-qubit channel: input_dim' +
            ' ({}) != output_dim ({})'.format(input_dim, output_dim))
    num_qubits = int(np.log2(input_dim))
    if 2**num_qubits != input_dim:
        raise QiskitError('Not an n-qubit channel: input_dim != 2 ** n')

Return true if dims correspond to an n - qubit channel .


def _hide_tick_lines_and_labels(axis):
    """
    Set visible property of ticklines and ticklabels of an axis to False
    """
    for item in axis.get_ticklines() + axis.get_ticklabels():
        item.set_visible(False)

def _hide_tick_lines_and_labels ( axis ) : for item in axis . get_ticklines ( ) + axis . get_ticklabels ( ) : item . set_visible ( False )


def set_label_convention(self, convention):
        """Set x, y and z labels according to one of conventions.

        Args:
            convention (str):
                One of the following:
                    - "original"
                    - "xyz"
                    - "sx sy sz"
                    - "01"
                    - "polarization jones"
                    - "polarization jones letters"
                    see also: http://en.wikipedia.org/wiki/Jones_calculus
                    - "polarization stokes"
                    see also: http://en.wikipedia.org/wiki/Stokes_parameters
        Raises:
            Exception: If convention is not valid.
        """
        ketex = "$\\left.|%s\\right\\rangle$"
        # \left.| is on purpose, so that every ket has the same size

        if convention == "original":
            self.xlabel = ['$x$', '']
            self.ylabel = ['$y$', '']
            self.zlabel = ['$\\left|0\\right>$', '$\\left|1\\right>$']
        elif convention == "xyz":
            self.xlabel = ['$x$', '']
            self.ylabel = ['$y$', '']
            self.zlabel = ['$z$', '']
        elif convention == "sx sy sz":
            self.xlabel = ['$s_x$', '']
            self.ylabel = ['$s_y$', '']
            self.zlabel = ['$s_z$', '']
        elif convention == "01":
            self.xlabel = ['', '']
            self.ylabel = ['', '']
            self.zlabel = ['$\\left|0\\right>$', '$\\left|1\\right>$']
        elif convention == "polarization jones":
            self.xlabel = [ketex % "\\nearrow\\hspace{-1.46}\\swarrow",
                           ketex % "\\nwarrow\\hspace{-1.46}\\searrow"]
            self.ylabel = [ketex % "\\circlearrowleft", ketex %
                           "\\circlearrowright"]
            self.zlabel = [ketex % "\\leftrightarrow", ketex % "\\updownarrow"]
        elif convention == "polarization jones letters":
            self.xlabel = [ketex % "D", ketex % "A"]
            self.ylabel = [ketex % "L", ketex % "R"]
            self.zlabel = [ketex % "H", ketex % "V"]
        elif convention == "polarization stokes":
            self.ylabel = ["$\\nearrow\\hspace{-1.46}\\swarrow$",
                           "$\\nwarrow\\hspace{-1.46}\\searrow$"]
            self.zlabel = ["$\\circlearrowleft$", "$\\circlearrowright$"]
            self.xlabel = ["$\\leftrightarrow$", "$\\updownarrow$"]
        else:
            raise Exception("No such convention.")

def
set_label_convention
(
self
,
convention
)
:
ketex
=
"$\\left.|%s\\right\\rangle$"
if
convention
==
"original"
:
self
.
xlabel
=
[
'$x$'
,
''
]
self
.
ylabel
=
[
'$y$'
,
''
]
self
.
zlabel
=
[
'$\\left|0\\right>$'
,
'$\\left|1\\right>$'
]
elif
convention
==
"xyz"
:
self
.
xlabel
=
[
'$x$'
,
''
]
self
.
ylabel
=
[
'$y$'
,
''
]
self
.
zlabel
=
[
'$z$'
,
''
]
elif
convention
==
"sx sy sz"
:
self
.
xlabel
=
[
'$s_x$'
,
''
]
self
.
ylabel
=
[
'$s_y$'
,
''
]
self
.
zlabel
=
[
'$s_z$'
,
''
]
elif
convention
==
"01"
:
self
.
xlabel
=
[
''
,
''
]
self
.
ylabel
=
[
''
,
''
]
self
.
zlabel
=
[
'$\\left|0\\right>$'
,
'$\\left|1\\right>$'
]
elif
convention
==
"polarization jones"
:
self
.
xlabel
=
[
ketex
%
"\\nearrow\\hspace{-1.46}\\swarrow"
,
ketex
%
"\\nwarrow\\hspace{-1.46}\\searrow"
]
self
.
ylabel
=
[
ketex
%
"\\circlearrowleft"
,
ketex
%
"\\circlearrowright"
]
self
.
zlabel
=
[
ketex
%
"\\leftrightarrow"
,
ketex
%
"\\updownarrow"
]
elif
convention
==
"polarization jones letters"
:
self
.
xlabel
=
[
ketex
%
"D"
,
ketex
%
"A"
]
self
.
ylabel
=
[
ketex
%
"L"
,
ketex
%
"R"
]
self
.
zlabel
=
[
ketex
%
"H"
,
ketex
%
"V"
]
elif
convention
==
"polarization stokes"
:
self
.
ylabel
=
[
"$\\nearrow\\hspace{-1.46}\\swarrow$"
,
"$\\nwarrow\\hspace{-1.46}\\searrow$"
]
self
.
zlabel
=
[
"$\\circlearrowleft$"
,
"$\\circlearrowright$"
]
self
.
xlabel
=
[
"$\\leftrightarrow$"
,
"$\\updownarrow$"
]
else
:
raise
Exception
(
"No such convention."
)

Set x y and z labels according to one of conventions .


def clear(self):
        """Resets Bloch sphere data sets to empty.
        """
        self.points = []
        self.vectors = []
        self.point_style = []
        self.annotations = []

def clear ( self ) : self . points = [ ] self . vectors = [ ] self . point_style = [ ] self . annotations = [ ]

Resets Bloch sphere data sets to empty .


def add_vectors(self, vectors):
        """Add a list of vectors to Bloch sphere.

        Args:
            vectors (array_like):
                Array with vectors of unit length or smaller.
        """
        if isinstance(vectors[0], (list, np.ndarray)):
            for vec in vectors:
                self.vectors.append(vec)
        else:
            self.vectors.append(vectors)

def add_vectors ( self , vectors ) : if isinstance ( vectors [ 0 ] , ( list , np . ndarray ) ) : for vec in vectors : self . vectors . append ( vec ) else : self . vectors . append ( vectors )