text: # -*- coding: utf-8 -*-
  
  # This code is part of Qiskit.
  #
  # (C) Copyright IBM 2017, 2018.
  #
  # This code is licensed under the Apache License, Version 2.0. You may
  # obtain a copy of this license in the LICENSE.txt file in the root directory
  # of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
  #
  # Any modifications or derivative works of this code must retain this
  # copyright notice, and modified files need to carry a notice indicating
  # that they have been altered from the originals.
  
  # pylint: disable=unused-import
  
  """Test Qiskit's QuantumCircuit class."""
  
  import os
  import tempfile
  import unittest
  import numpy as np
  
  import qiskit.extensions.simulator
  from qiskit import BasicAer
  from qiskit.circuit import QuantumRegister, ClassicalRegister, QuantumCircuit, Qubit, Clbit
  from qiskit import execute
  from qiskit import QiskitError
  from qiskit.quantum_info import state_fidelity
  from qiskit.test import QiskitTestCase
  
  
  class TestCircuitRegisters(QiskitTestCase):
      """QuantumCircuit Registers tests."""
  
      def test_qregs(self):
          """Test getting quantum registers from circuit.
          """
          qr1 = QuantumRegister(10, "q")
          self.assertEqual(qr1.name, "q")
          self.assertEqual(qr1.size, 10)
          self.assertEqual(type(qr1), QuantumRegister)
  
      def test_cregs(self):
          """Test getting quantum registers from circuit.
          """
          cr1 = ClassicalRegister(10, "c")
          self.assertEqual(cr1.name, "c")
          self.assertEqual(cr1.size, 10)
          self.assertEqual(type(cr1), ClassicalRegister)
  
      def test_qarg_negative_size(self):
          """Test attempt to create a negative size QuantumRegister.
          """
          self.assertRaises(qiskit.exceptions.QiskitError, QuantumRegister, -1)
  
      def test_qarg_string_size(self):
          """Test attempt to create a non-integer size QuantumRegister.
          """
          self.assertRaises(qiskit.exceptions.QiskitError, QuantumRegister, 'string')
  
      def test_qarg_numpy_int_size(self):
          """Test castable to integer size QuantumRegister.
          """
          np_int = np.dtype('int').type(10)
          qr1 = QuantumRegister(np_int, "q")
          self.assertEqual(qr1.name, "q")
          self.assertEqual(qr1.size, 10)
          self.assertEqual(type(qr1), QuantumRegister)
  
      def test_numpy_array_of_registers(self):
          """Test numpy array of Registers .
          See https://github.com/Qiskit/qiskit-terra/issues/1898
          """
          qrs = [QuantumRegister(2, name='q%s' % i) for i in range(5)]
          qreg_array = np.array([], dtype=object, ndmin=1)
          qreg_array = np.append(qreg_array, qrs)
  
          expected = [qrs[0][0], qrs[0][1],
                      qrs[1][0], qrs[1][1],
                      qrs[2][0], qrs[2][1],
                      qrs[3][0], qrs[3][1],
                      qrs[4][0], qrs[4][1]]
  
          self.assertEqual(len(qreg_array), 10)
          self.assertEqual(qreg_array.tolist(), expected)
  
      def test_negative_index(self):
          """Test indexing from the back
          """
          qr1 = QuantumRegister(10, "q")
          cr1 = ClassicalRegister(10, "c")
          self.assertEqual(qr1[-1], qr1[9])
          self.assertEqual(qr1[-3:-1], [qr1[7], qr1[8]])
          self.assertEqual(len(cr1[0:-2]), 8)
  
      def test_reg_equal(self):
          """Test getting quantum registers from circuit.
          """
          qr1 = QuantumRegister(1, "q")
          qr2 = QuantumRegister(2, "q")
          cr1 = ClassicalRegister(1, "q")
  
          self.assertEqual(qr1, qr1)
          self.assertNotEqual(qr1, qr2)
          self.assertNotEqual(qr1, cr1)
  
      def test_qubits(self):
          """Test qubits() method.
          """
          qr1 = QuantumRegister(1, "q1")
          cr1 = ClassicalRegister(3, "c1")
          qr2 = QuantumRegister(2, "q2")
          qc = QuantumCircuit(qr2, cr1, qr1)
  
          qubtis = qc.qubits
  
          self.assertEqual(qubtis[0], qr2[0])
          self.assertEqual(qubtis[1], qr2[1])
          self.assertEqual(qubtis[2], qr1[0])
  
      def test_clbits(self):
          """Test clbits() method.
          """
          qr1 = QuantumRegister(1, "q1")
          cr1 = ClassicalRegister(2, "c1")
          qr2 = QuantumRegister(2, "q2")
          cr2 = ClassicalRegister(1, "c2")
          qc = QuantumCircuit(qr2, cr2, qr1, cr1)
  
          clbtis = qc.clbits
  
          self.assertEqual(clbtis[0], cr2[0])
          self.assertEqual(clbtis[1], cr1[0])
          self.assertEqual(clbtis[2], cr1[1])
  
      def test_qregs_circuit(self):
          """Test getting quantum registers from circuit.
          """
          qr1 = QuantumRegister(1)
          qr2 = QuantumRegister(2)
          qc = QuantumCircuit(qr1, qr2)
          q_regs = qc.qregs
          self.assertEqual(len(q_regs), 2)
          self.assertEqual(q_regs[0], qr1)
          self.assertEqual(q_regs[1], qr2)
  
      def test_cregs_circuit(self):
          """Test getting classical registers from circuit.
          """
          cr1 = ClassicalRegister(1)
          cr2 = ClassicalRegister(2)
          cr3 = ClassicalRegister(3)
          qc = QuantumCircuit(cr1, cr2, cr3)
          c_regs = qc.cregs
          self.assertEqual(len(c_regs), 3)
          self.assertEqual(c_regs[0], cr1)
          self.assertEqual(c_regs[1], cr2)
  
      def test_basic_slice(self):
          """simple slice test"""
          qr = QuantumRegister(5)
          cr = ClassicalRegister(5)
          self.assertEqual(len(qr[0:3]), 3)
          self.assertEqual(len(cr[0:3]), 3)
  
      def test_apply_gate_to_slice(self):
          """test applying gate to register slice"""
          sli = slice(0, 9, 2)
          qr = QuantumRegister(10)
          cr = ClassicalRegister(10)
          qc = QuantumCircuit(qr, cr)
          qc.h(qr[0:9:2])
          for i, index in enumerate(range(*sli.indices(sli.stop))):
              self.assertEqual(qc.data[i][1][0].index, index)
  
      def test_apply_barrier_to_slice(self):
          """test applying barrier to register slice"""
          n_qubits = 10
          qr = QuantumRegister(n_qubits)
          cr = ClassicalRegister(n_qubits)
          qc = QuantumCircuit(qr, cr)
          qc.barrier(qr)
          # barrier works a little different than normal gates for expansion
          # test full register
          self.assertEqual(len(qc.data), 1)
          self.assertEqual(qc.data[0][0].name, 'barrier')
          self.assertEqual(len(qc.data[0][1]), n_qubits)
          for i, bit in enumerate(qc.data[0][1]):
              self.assertEqual(bit.index, i)
          # test slice
          n_qubits = 2
          qc = QuantumCircuit(qr, cr)
          qc.barrier(qr[0:n_qubits])
          self.log.info(qc.qasm())
          self.assertEqual(len(qc.data), 1)
          self.assertEqual(qc.data[0][0].name, 'barrier')
          self.assertEqual(len(qc.data[0][1]), n_qubits)
          for i in range(n_qubits):
              self.assertEqual(qc.data[0][1][i].index, i)
  
      def test_apply_ccx_to_slice(self):
          """test applying ccx to register slice"""
          qcontrol = QuantumRegister(10)
          qcontrol2 = QuantumRegister(10)
          qtarget = QuantumRegister(5)
          qtarget2 = QuantumRegister(10)
          qc = QuantumCircuit(qcontrol, qtarget)
          # test slice with skip and full register target
          qc.ccx(qcontrol[1::2], qcontrol[0::2], qtarget)
          self.assertEqual(len(qc.data), 5)
          for i, ictl, (gate, qargs, _) in zip(range(len(qc.data)), range(0, 10, 2), qc.data):
              self.assertEqual(gate.name, 'ccx')
              self.assertEqual(len(qargs), 3)
              self.assertIn(qargs[0].index, [ictl, ictl + 1])
              self.assertIn(qargs[1].index, [ictl, ictl + 1])
              self.assertEqual(qargs[2].index, i)
          # test decrementing slice
          qc = QuantumCircuit(qcontrol, qtarget)
          qc.ccx(qcontrol[2:0:-1], qcontrol[4:6], qtarget[0:2])
          self.assertEqual(len(qc.data), 2)
          for (gate, qargs, _), ictl1, ictl2, itgt in zip(qc.data, range(2, 0, -1),
                                                          range(4, 6), range(0, 2)):
              self.assertEqual(gate.name, 'ccx')
              self.assertEqual(len(qargs), 3)
              self.assertEqual(qargs[0].index, ictl1)
              self.assertEqual(qargs[1].index, ictl2)
              self.assertEqual(qargs[2].index, itgt)
          # test register expansion in ccx
          qc = QuantumCircuit(qcontrol, qcontrol2, qtarget2)
          qc.ccx(qcontrol, qcontrol2, qtarget2)
          for i, (gate, qargs, _) in enumerate(qc.data):
              self.assertEqual(gate.name, 'ccx')
              self.assertEqual(len(qargs), 3)
              self.assertEqual(qargs[0].index, i)
              self.assertEqual(qargs[1].index, i)
              self.assertEqual(qargs[2].index, i)
  
      def test_cswap_on_slice(self):
          """test applying cswap to register slice"""
          qr1 = QuantumRegister(10)
          qr2 = QuantumRegister(5)
          qc = QuantumCircuit(qr1, qr2)
          qc.cswap(qr2[3::-1], qr1[1:9:2], qr1[2:9:2])
          qc.cswap(qr2[0], qr1[1], qr1[2])
          qc.cswap([qr2[0]], [qr1[1]], [qr1[2]])
          self.assertRaises(qiskit.exceptions.QiskitError, qc.cswap, qr2[4::-1],
                            qr1[1:9:2], qr1[2:9:2])
  
      def test_apply_ccx_to_empty_slice(self):
          """test applying ccx to non-register raises"""
          qr = QuantumRegister(10)
          cr = ClassicalRegister(10)
          qc = QuantumCircuit(qr, cr)
          self.assertRaises(qiskit.exceptions.QiskitError, qc.ccx, qr[2:0], qr[4:2], qr[7:5])
  
      def test_apply_cx_to_non_register(self):
          """test applying ccx to non-register raises"""
          qr = QuantumRegister(10)
          cr = ClassicalRegister(10)
          qc = QuantumCircuit(qr, cr)
          self.assertRaises(qiskit.exceptions.QiskitError, qc.cx, qc[0:2], qc[2:4])
  
      def test_apply_ch_to_slice(self):
          """test applying ch to slice"""
          qr = QuantumRegister(10)
          cr = ClassicalRegister(10)
          # test slice
          qc = QuantumCircuit(qr, cr)
          ctl_slice = slice(0, 2)
          tgt_slice = slice(2, 4)
          qc.ch(qr[ctl_slice], qr[tgt_slice])
          for (gate, qargs, _), ictrl, itgt in zip(qc.data, range(0, 2), range(2, 4)):
              self.assertEqual(gate.name, 'ch')
              self.assertEqual(len(qargs), 2)
              self.assertEqual(qargs[0].index, ictrl)
              self.assertEqual(qargs[1].index, itgt)
          # test single qubit args
          qc = QuantumCircuit(qr, cr)
          qc.ch(qr[0], qr[1])
          self.assertEqual(len(qc.data), 1)
          op, qargs, _ = qc.data[0]
          self.assertEqual(op.name, 'ch')
          self.assertEqual(qargs[0].index, 0)
          self.assertEqual(qargs[1].index, 1)
  
      def test_measure_slice(self):
          """test measure slice"""
          qr = QuantumRegister(10)
          cr = ClassicalRegister(10)
          cr2 = ClassicalRegister(5)
          qc = QuantumCircuit(qr, cr)
          qc.measure(qr[0:2], cr[2:4])
          for (gate, qargs, cargs), ictrl, itgt in zip(qc.data, range(0, 2), range(2, 4)):
              self.assertEqual(gate.name, 'measure')
              self.assertEqual(len(qargs), 1)
              self.assertEqual(len(cargs), 1)
              self.assertEqual(qargs[0].index, ictrl)
              self.assertEqual(cargs[0].index, itgt)
          # test single element slice
          qc = QuantumCircuit(qr, cr)
          qc.measure(qr[0:1], cr[2:3])
          for (gate, qargs, cargs), ictrl, itgt in zip(qc.data, range(0, 1), range(2, 3)):
              self.assertEqual(gate.name, 'measure')
              self.assertEqual(len(qargs), 1)
              self.assertEqual(len(cargs), 1)
              self.assertEqual(qargs[0].index, ictrl)
              self.assertEqual(cargs[0].index, itgt)
          # test tuple
          qc = QuantumCircuit(qr, cr)
          qc.measure(qr[0], cr[2])
          self.assertEqual(len(qc.data), 1)
          op, qargs, cargs = qc.data[0]
          self.assertEqual(op.name, 'measure')
          self.assertEqual(len(qargs), 1)
          self.assertEqual(len(cargs), 1)
          self.assertTrue(isinstance(qargs[0], Qubit))
          self.assertTrue(isinstance(cargs[0], Clbit))
          self.assertEqual(qargs[0].index, 0)
          self.assertEqual(cargs[0].index, 2)
          # test full register
          qc = QuantumCircuit(qr, cr)
          qc.measure(qr, cr)
          for (gate, qargs, cargs), ictrl, itgt in zip(qc.data, range(len(qr)), range(len(cr))):
              self.assertEqual(gate.name, 'measure')
              self.assertEqual(len(qargs), 1)
              self.assertEqual(len(cargs), 1)
              self.assertEqual(qargs[0].index, ictrl)
              self.assertEqual(cargs[0].index, itgt)
          # test mix slice full register
          qc = QuantumCircuit(qr, cr2)
          qc.measure(qr[::2], cr2)
          for (gate, qargs, cargs), ictrl, itgt in zip(qc.data, range(0, 10, 2), range(len(cr2))):
              self.assertEqual(gate.name, 'measure')
              self.assertEqual(len(qargs), 1)
              self.assertEqual(len(cargs), 1)
              self.assertEqual(qargs[0].index, ictrl)
              self.assertEqual(cargs[0].index, itgt)
  
      def test_measure_slice_raises(self):
          """test raising exception for strange measures"""
          qr = QuantumRegister(10)
          cr = ClassicalRegister(10)
          qc = QuantumCircuit(qr, cr)
          with self.assertRaises(QiskitError):
              qc.measure(qr[0:2], cr[2])
          # this is ok
          qc.measure(qr[0], cr[0:2])
  
      def test_list_indexing(self):
          """test list indexing"""
          qr = QuantumRegister(10)
          cr = QuantumRegister(10)
          qc = QuantumCircuit(qr, cr)
          ind = [0, 1, 8, 9]
          qc.h(qr[ind])
          self.assertEqual(len(qc.data), len(ind))
          for (gate, qargs, _), index in zip(qc.data, ind):
              self.assertEqual(gate.name, 'h')
              self.assertEqual(len(qargs), 1)
              self.assertEqual(qargs[0].index, index)
          qc = QuantumCircuit(qr, cr)
          ind = [0, 1, 8, 9]
          qc.cx(qr[ind], qr[2:6])
          for (gate, qargs, _), ind1, ind2 in zip(qc.data, ind, range(2, 6)):
              self.assertEqual(gate.name, 'cx')
              self.assertEqual(len(qargs), 2)
              self.assertEqual(qargs[0].index, ind1)
              self.assertEqual(qargs[1].index, ind2)
  
  
  class TestCircuitBit(QiskitTestCase):
      """QuantumCircuit Registers tests."""
  
      def test_bit_getitem(self):
          """ Deprecated Bit.__getitem__.
          """
          qubit = QuantumRegister(1, "q")[0]
  
          with self.assertWarns(DeprecationWarning):
              self.assertEqual(qubit[0], qubit.register)
              self.assertEqual(qubit[1], qubit.index)
  
      def test_gate_with_tuples(self):
          """ Deprecated gate parameters as tuples"""
          qr = QuantumRegister(1)
          qc = QuantumCircuit(qr)
  
          expected = QuantumCircuit(qr)
          expected.h(qr[0])
  
          with self.assertWarns(DeprecationWarning):
              qc.h((qr, 0))
          self.assertEqual(qc, expected)
  
      def test_gate_with_tuple_list(self):
          """ Deprecated gate parameters as tuple list"""
          qr = QuantumRegister(2)
          qc = QuantumCircuit(qr)
  
          expected = QuantumCircuit(qr)
          expected.h([qr[0], qr[1]])
  
          with self.assertWarns(DeprecationWarning):
              qc.h([(qr, 0), (qr, 1)])
          self.assertEqual(qc, expected)
  