Exemplo n.º 1
0
    def test_z2_symmetry(self):
        """ Test mapping to qubit operator with z2 symmetry tapering """
        z2_sector = [-1, 1, -1]

        def finder(z2_symmetries: Z2Symmetries) -> Optional[List[int]]:
            return z2_sector if not z2_symmetries.is_empty() else None

        def find_none(_z2_symmetries: Z2Symmetries) -> Optional[List[int]]:
            return None

        mapper = JordanWignerMapper()
        qubit_conv = QubitConverter(mapper, z2symmetry_reduction='auto')

        with self.subTest('Locator returns None, should be untapered operator'):
            qubit_op = qubit_conv.convert(self.h2_op, sector_locator=find_none)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW)

        qubit_op = qubit_conv.convert(self.h2_op, sector_locator=finder)
        self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW_TAPERED)

        with self.subTest('convert_match()'):
            qubit_op = qubit_conv.convert_match(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW_TAPERED)
            self.assertIsNone(qubit_conv.num_particles)
            self.assertListEqual(qubit_conv.z2symmetries.tapering_values, z2_sector)
Exemplo n.º 2
0
    def test_chc_vscf(self):
        """ chc vscf test """

        co2_2modes_2modals_2body = [
            [[[[0, 0, 0]], 320.8467332810141], [[[0, 1, 1]],
                                                1760.878530705873],
             [[[1, 0, 0]], 342.8218290247543], [[[1, 1, 1]],
                                                1032.396323618631]],
            [[[[0, 0, 0], [1, 0, 0]], -57.34003649795117],
             [[[0, 0, 1], [1, 0, 0]], -56.33205925807966],
             [[[0, 1, 0], [1, 0, 0]], -56.33205925807966],
             [[[0, 1, 1], [1, 0, 0]], -60.13032761856809],
             [[[0, 0, 0], [1, 0, 1]], -65.09576309934431],
             [[[0, 0, 1], [1, 0, 1]], -62.2363839133389],
             [[[0, 1, 0], [1, 0, 1]], -62.2363839133389],
             [[[0, 1, 1], [1, 0, 1]], -121.5533969109279],
             [[[0, 0, 0], [1, 1, 0]], -65.09576309934431],
             [[[0, 0, 1], [1, 1, 0]], -62.2363839133389],
             [[[0, 1, 0], [1, 1, 0]], -62.2363839133389],
             [[[0, 1, 1], [1, 1, 0]], -121.5533969109279],
             [[[0, 0, 0], [1, 1, 1]], -170.744837386338],
             [[[0, 0, 1], [1, 1, 1]], -167.7433236025723],
             [[[0, 1, 0], [1, 1, 1]], -167.7433236025723],
             [[[0, 1, 1], [1, 1, 1]], -179.0536532281924]]
        ]
        num_modes = 2
        num_modals = [2, 2]

        vibrational_op_labels = _create_labels(co2_2modes_2modals_2body)
        vibr_op = VibrationalOp(vibrational_op_labels, num_modes, num_modals)

        converter = QubitConverter(DirectMapper())

        qubit_op = converter.convert_match(vibr_op)

        init_state = VSCF(num_modals)

        num_qubits = sum(num_modals)
        excitations = []
        excitations += generate_vibration_excitations(num_excitations=1,
                                                      num_modals=num_modals)
        excitations += generate_vibration_excitations(num_excitations=2,
                                                      num_modals=num_modals)
        chc_ansatz = CHC(num_qubits,
                         ladder=False,
                         excitations=excitations,
                         initial_state=init_state)

        backend = QuantumInstance(
            BasicAer.get_backend('statevector_simulator'),
            seed_transpiler=2,
            seed_simulator=2)
        optimizer = COBYLA(maxiter=1000)

        algo = VQE(chc_ansatz, optimizer=optimizer, quantum_instance=backend)
        vqe_result = algo.compute_minimum_eigenvalue(qubit_op)
        energy = vqe_result.optimal_value

        self.assertAlmostEqual(energy, self.reference_energy, places=4)
Exemplo n.º 3
0
 def test_qubits_2_py_h2(self):
     """ qubits 2 py h2 test """
     num_particles = (1, 1)
     converter = QubitConverter(ParityMapper(), two_qubit_reduction=True)
     converter.force_match(num_particles=num_particles)
     state = HartreeFock(4, num_particles, converter)
     ref = QuantumCircuit(2)
     ref.x(0)
     self.assertEqual(state, ref)
Exemplo n.º 4
0
    def test_two_qubit_reduction(self):
        """ Test mapping to qubit operator with two qubit reduction """
        mapper = ParityMapper()
        qubit_conv = QubitConverter(mapper, two_qubit_reduction=True)

        with self.subTest('Two qubit reduction ignored as no num particles given'):
            qubit_op = qubit_conv.convert(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY)
            self.assertIsNone(qubit_conv.num_particles)

        with self.subTest('Two qubit reduction, num particles given'):
            qubit_op = qubit_conv.convert(self.h2_op, self.num_particles)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY_2Q_REDUCED)
            self.assertEqual(qubit_conv.num_particles, self.num_particles)

        with self.subTest('convert_match()'):
            qubit_op = qubit_conv.convert_match(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY_2Q_REDUCED)
            self.assertEqual(qubit_conv.num_particles, self.num_particles)

        with self.subTest('State is reset (Num particles lost)'):
            qubit_op = qubit_conv.convert(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY)
            self.assertIsNone(qubit_conv.num_particles)

        with self.subTest('Num particles given again'):
            qubit_op = qubit_conv.convert(self.h2_op, self.num_particles)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY_2Q_REDUCED)

        with self.subTest('Set for no two qubit reduction'):
            qubit_conv.two_qubit_reduction = False
            self.assertFalse(qubit_conv.two_qubit_reduction)
            qubit_op = qubit_conv.convert(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY)
Exemplo n.º 5
0
    def test_molecular_problem_sector_locator_z2_symmetry(self):
        """ Test mapping to qubit operator with z2 symmetry tapering and two qubit reduction """

        driver = HDF5Driver(hdf5_input=self.get_resource_path('test_driver_hdf5.hdf5',
                                                              'drivers/hdf5d'))
        problem = ElectronicStructureProblem(driver)

        mapper = JordanWignerMapper()
        qubit_conv = QubitConverter(mapper, two_qubit_reduction=True, z2symmetry_reduction='auto')
        qubit_op = qubit_conv.convert(problem.second_q_ops()[0], self.num_particles,
                                      sector_locator=problem.symmetry_sector_locator)
        self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW_TAPERED)
Exemplo n.º 6
0
    def setUp(self):
        super().setUp()
        algorithm_globals.random_seed = 42

        driver = HDF5Driver(hdf5_input=self.get_resource_path('test_driver_hdf5.hdf5',
                                                              'drivers/hdf5d'))
        problem = ElectronicStructureProblem(driver)
        second_q_ops = problem.second_q_ops()
        converter = QubitConverter(mapper=ParityMapper(), two_qubit_reduction=True)
        num_particles = (problem.molecule_data_transformed.num_alpha,
                         problem.molecule_data_transformed.num_beta)
        self.qubit_op = converter.convert(second_q_ops[0], num_particles)
        self.aux_ops = converter.convert_match(second_q_ops[1:])
        self.reference_energy = -1.857275027031588
Exemplo n.º 7
0
    def setUp(self):
        super().setUp()
        algorithm_globals.random_seed = 8
        self.driver = _DummyBosonicDriver()
        self.qubit_converter = QubitConverter(DirectMapper())
        self.basis_size = 2
        self.truncation_order = 2

        self.vibrational_problem = VibrationalStructureProblem(
            self.driver, self.basis_size, self.truncation_order)

        self.qubit_converter = QubitConverter(DirectMapper())
        self.vibrational_problem.second_q_ops()
        self.watson_hamiltonian = self.vibrational_problem.molecule_data
        self.num_modals = [self.basis_size] * self.watson_hamiltonian.num_modes
    def setUp(self):
        super().setUp()
        self.driver = HDF5Driver(
            self.get_resource_path('test_driver_hdf5.hdf5', 'drivers/hdf5d'))
        self.seed = 700
        algorithm_globals.random_seed = self.seed

        self.reference_energy = -1.1373060356951838

        self.qubit_converter = QubitConverter(JordanWignerMapper())
        self.electronic_structure_problem = ElectronicStructureProblem(
            self.driver)

        self.num_spin_orbitals = 4
        self.num_particles = (1, 1)
Exemplo n.º 9
0
def _build_single_hopping_operator(
        excitation: Tuple[Tuple[int, ...], Tuple[int,
                                                 ...]], num_spin_orbitals: int,
        qubit_converter: QubitConverter) -> Tuple[PauliSumOp, List[bool]]:
    label = ['I'] * num_spin_orbitals
    for occ in excitation[0]:
        label[occ] = '+'
    for unocc in excitation[1]:
        label[unocc] = '-'
    fer_op = FermionicOp((''.join(label), 4.0**len(excitation[0])))

    qubit_op: PauliSumOp = qubit_converter.convert_match(fer_op)
    z2_symmetries = qubit_converter.z2symmetries

    commutativities = []
    if not z2_symmetries.is_empty():
        for symmetry in z2_symmetries.symmetries:
            symmetry_op = PauliSumOp.from_list([(symmetry.to_label(), 1.0)])
            commuting = qubit_op.primitive.table.commutes_with_all(
                symmetry_op.primitive.table)
            anticommuting = qubit_op.primitive.table.anticommutes_with_all(
                symmetry_op.primitive.table)

            if commuting != anticommuting:  # only one of them is True
                if commuting:
                    commutativities.append(True)
                elif anticommuting:
                    commutativities.append(False)
            else:
                raise QiskitNatureError(
                    "Symmetry {} is nor commute neither anti-commute "
                    "to exciting operator.".format(symmetry.to_label()))

    return qubit_op, commutativities
Exemplo n.º 10
0
    def __init__(self, num_spin_orbitals: int, num_particles: Tuple[int, int],
                 qubit_converter: QubitConverter) -> None:
        """
        Args:
            num_spin_orbitals: The number of spin orbitals, has a min. value of 1.
            num_particles: The number of particles as a tuple storing the number of alpha- and
                           beta-spin electrons in the first and second number, respectively.
            qubit_converter: a QubitConverter instance.
        """

        # get the bitstring encoding the Hartree Fock state
        bitstr = hartree_fock_bitstring(num_spin_orbitals, num_particles)

        # encode the bitstring as a `FermionicOp`
        label = ['+' if bit else 'I' for bit in bitstr]
        bitstr_op = FermionicOp(''.join(label))

        # map the `FermionicOp` to a qubit operator
        qubit_op: PauliSumOp = qubit_converter.convert_match(bitstr_op)

        # construct the circuit
        qr = QuantumRegister(qubit_op.num_qubits, 'q')
        super().__init__(qr, name='HF')

        # Add gates in the right positions: we are only interested in the `X` gates because we want
        # to create particles (0 -> 1) where the initial state introduced a creation (`+`) operator.
        for i, bit in enumerate(qubit_op.primitive.table.X[0]):
            if bit:
                self.x(i)
Exemplo n.º 11
0
    def test_h2_bopes_sampler(self):
        """Test BOPES Sampler on H2"""
        seed = 50
        algorithm_globals.random_seed = seed

        # Molecule
        dof = partial(Molecule.absolute_distance, atom_pair=(1, 0))
        m = Molecule(geometry=[['H', [0., 0., 1.]], ['H', [0., 0.45, 1.]]],
                     degrees_of_freedom=[dof])

        mapper = ParityMapper()
        converter = QubitConverter(mapper=mapper, two_qubit_reduction=True)

        driver = PySCFDriver(molecule=m)
        problem = ElectronicStructureProblem(driver)

        solver = NumPyMinimumEigensolver()
        me_gss = GroundStateEigensolver(converter, solver)

        # BOPES sampler
        sampler = BOPESSampler(gss=me_gss)

        # absolute internuclear distance in Angstrom
        points = [0.7, 1.0, 1.3]
        results = sampler.sample(problem, points)

        points_run = results.points
        energies = results.energies

        np.testing.assert_array_almost_equal(points_run, [0.7, 1.0, 1.3])
        np.testing.assert_array_almost_equal(
            energies, [-1.13618945, -1.10115033, -1.03518627], decimal=2)
Exemplo n.º 12
0
 def test_qubits_6_py_lih(self):
     """ qubits 6 py lih test """
     num_particles = (1, 1)
     converter = QubitConverter(ParityMapper(), two_qubit_reduction=True)
     z2symmetries = Z2Symmetries(
         symmetries=[Pauli('ZIZIZIZI'),
                     Pauli('ZZIIZZII')],
         sq_paulis=[Pauli('IIIIIIXI'), Pauli('IIIIIXII')],
         sq_list=[2, 3],
         tapering_values=[1, 1],
     )
     converter.force_match(num_particles=num_particles,
                           z2symmetries=z2symmetries)
     state = HartreeFock(10, num_particles, converter)
     ref = QuantumCircuit(6)
     ref.x([0, 1])
     self.assertEqual(state, ref)
 def test_oh_uhf_bk(self):
     """ oh uhf bk test """
     driver = PySCFDriver(atom=self.o_h, unit=UnitsType.ANGSTROM,
                          charge=0, spin=1, basis='sto-3g',
                          hf_method=HFMethodType.UHF)
     result = self._run_driver(driver,
                               converter=QubitConverter(BravyiKitaevMapper()))
     self._assert_energy_and_dipole(result, 'oh')
 def test_oh_rohf_parity(self):
     """ oh rohf parity test """
     driver = PySCFDriver(atom=self.o_h, unit=UnitsType.ANGSTROM,
                          charge=0, spin=1, basis='sto-3g',
                          hf_method=HFMethodType.ROHF)
     result = self._run_driver(driver,
                               converter=QubitConverter(ParityMapper()))
     self._assert_energy_and_dipole(result, 'oh')
Exemplo n.º 15
0
    def test_puccd_ansatz(self, num_spin_orbitals, num_particles, expect):
        """Tests the PUCCD Ansatz."""
        converter = QubitConverter(JordanWignerMapper())

        ansatz = PUCCD(qubit_converter=converter,
                       num_particles=num_particles,
                       num_spin_orbitals=num_spin_orbitals)

        assert_ucc_like_ansatz(self, ansatz, num_spin_orbitals, expect)
Exemplo n.º 16
0
    def test_ucc_ansatz(self, excitations, num_modals, expect):
        """Tests the UVCC Ansatz."""
        converter = QubitConverter(DirectMapper())

        ansatz = UVCC(qubit_converter=converter,
                      num_modals=num_modals,
                      excitations=excitations)

        assert_ucc_like_ansatz(self, ansatz, num_modals, expect)
 def test_lih_rhf_bk(self):
     """ lih rhf bk test """
     driver = PySCFDriver(atom=self.lih, unit=UnitsType.ANGSTROM,
                          charge=0, spin=0, basis='sto-3g',
                          hf_method=HFMethodType.RHF)
     result = self._run_driver(driver,
                               converter=QubitConverter(BravyiKitaevMapper()),
                               transformers=[FreezeCoreTransformer()])
     self._assert_energy_and_dipole(result, 'lih')
 def test_oh_uhf_parity_2q(self):
     """ oh uhf parity 2q test """
     driver = PySCFDriver(atom=self.o_h, unit=UnitsType.ANGSTROM,
                          charge=0, spin=1, basis='sto-3g',
                          hf_method=HFMethodType.UHF)
     result = self._run_driver(driver,
                               converter=QubitConverter(ParityMapper(),
                                                        two_qubit_reduction=True))
     self._assert_energy_and_dipole(result, 'oh')
 def test_lih_rhf_parity_2q(self):
     """ lih rhf parity 2q test """
     driver = PySCFDriver(atom=self.lih, unit=UnitsType.ANGSTROM,
                          charge=0, spin=0, basis='sto-3g',
                          hf_method=HFMethodType.RHF)
     result = self._run_driver(driver,
                               converter=QubitConverter(ParityMapper(),
                                                        two_qubit_reduction=True),
                               transformers=[FreezeCoreTransformer()])
     self._assert_energy_and_dipole(result, 'lih')
Exemplo n.º 20
0
    def test_puccd_ansatz_with_singles(self, num_spin_orbitals, num_particles,
                                       include_singles, expect):
        """Tests the PUCCD Ansatz with included single excitations."""
        converter = QubitConverter(JordanWignerMapper())

        ansatz = PUCCD(qubit_converter=converter,
                       num_particles=num_particles,
                       num_spin_orbitals=num_spin_orbitals,
                       include_singles=include_singles)

        assert_ucc_like_ansatz(self, ansatz, num_spin_orbitals, expect)
    def setUp(self):
        super().setUp()
        self.driver = PySCFDriver(atom='H 0 0 0.735; H 0 0 0', basis='631g')

        self.qubit_converter = QubitConverter(ParityMapper(),
                                              two_qubit_reduction=True)

        self.electronic_structure_problem = ElectronicStructureProblem(
            self.driver, [FreezeCoreTransformer()])

        self.num_spin_orbitals = 8
        self.num_particles = (1, 1)

        # because we create the initial state and ansatzes early, we need to ensure the qubit
        # converter already ran such that convert_match works as expected
        _ = self.qubit_converter.convert(
            self.electronic_structure_problem.second_q_ops()[0],
            self.num_particles)

        self.reference_energy_pUCCD = -1.1434447924298028
        self.reference_energy_UCCD0 = -1.1476045878481704
        self.reference_energy_UCCD0full = -1.1515491334334347
        # reference energy of UCCSD/VQE with tapering everywhere
        self.reference_energy_UCCSD = -1.1516142309717594
        # reference energy of UCCSD/VQE when no tapering on excitations is used
        self.reference_energy_UCCSD_no_tap_exc = -1.1516142309717594
        # excitations for succ
        self.reference_singlet_double_excitations = [[0, 1, 4,
                                                      5], [0, 1, 4, 6],
                                                     [0, 1, 4,
                                                      7], [0, 2, 4, 6],
                                                     [0, 2, 4, 7],
                                                     [0, 3, 4, 7]]
        # groups for succ_full
        self.reference_singlet_groups = [[[0, 1, 4, 5]],
                                         [[0, 1, 4, 6], [0, 2, 4, 5]],
                                         [[0, 1, 4, 7], [0, 3, 4, 5]],
                                         [[0, 2, 4, 6]],
                                         [[0, 2, 4, 7], [0, 3, 4, 6]],
                                         [[0, 3, 4, 7]]]
Exemplo n.º 22
0
    def setUp(self):
        super().setUp()

        self.converter = QubitConverter(JordanWignerMapper())

        self.seed = 50
        self.quantum_instance = QuantumInstance(
            BasicAer.get_backend('statevector_simulator'),
            shots=1,
            seed_simulator=self.seed,
            seed_transpiler=self.seed)

        self._vqe_uvcc_factory = VQEUVCCFactory(self.quantum_instance)
    def setUp(self):
        super().setUp()
        algorithm_globals.random_seed = 8
        self.reference_energies = [1889.95738428, 3294.21806197, 4287.26821341, 5819.76975784]

        self.driver = _DummyBosonicDriver()
        self.qubit_converter = QubitConverter(DirectMapper())
        self.basis_size = 2
        self.truncation_order = 2

        self.vibrational_problem = VibrationalStructureProblem(
            self.driver, self.basis_size, self.truncation_order
        )
    def _run_driver(driver: FermionicDriver,
                    converter: QubitConverter = QubitConverter(
                        JordanWignerMapper()),
                    transformers: Optional[List[BaseTransformer]] = None):

        problem = ElectronicStructureProblem(driver, transformers)

        solver = NumPyMinimumEigensolver()

        gsc = GroundStateEigensolver(converter, solver)

        result = gsc.solve(problem)
        return result
Exemplo n.º 25
0
def _build_single_hopping_operator(
        excitation: Tuple[Tuple[int, ...], Tuple[int, ...]],
        num_modals: List[int], qubit_converter: QubitConverter) -> PauliSumOp:
    sum_modes = sum(num_modals)

    label = ['I'] * sum_modes
    for occ in excitation[0]:
        label[occ] = '+'
    for unocc in excitation[1]:
        label[unocc] = '-'
    vibrational_op = VibrationalOp(''.join(label), len(num_modals), num_modals)
    qubit_op: PauliSumOp = qubit_converter.convert_match(vibrational_op)

    return qubit_op
Exemplo n.º 26
0
    def setUp(self):
        super().setUp()

        try:
            self.driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 0.735',
                                      unit=UnitsType.ANGSTROM,
                                      basis='sto3g')
        except QiskitNatureError:
            self.skipTest('PYSCF driver does not appear to be installed')
            return

        self.problem = ElectronicStructureProblem(self.driver)

        self.expected = -1.85727503

        self.qubit_converter = QubitConverter(ParityMapper())
Exemplo n.º 27
0
    def setUp(self):
        super().setUp()
        algorithm_globals.random_seed = 8
        try:
            self.driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 0.75',
                                      unit=UnitsType.ANGSTROM,
                                      charge=0,
                                      spin=0,
                                      basis='sto3g')
        except QiskitNatureError:
            self.skipTest('PYSCF driver does not appear to be installed')

        self.qubit_converter = QubitConverter(JordanWignerMapper())
        self.electronic_structure_problem = ElectronicStructureProblem(
            self.driver)
        self.electronic_structure_problem.second_q_ops()
        self.q_molecule = self.electronic_structure_problem.molecule_data
    def test_uccsd_hf_qasm(self):
        """ uccsd hf test with qasm_simulator. """
        qubit_converter = QubitConverter(ParityMapper())
        ansatz = self._prepare_uccsd_hf(qubit_converter)

        backend = BasicAer.get_backend('qasm_simulator')

        optimizer = SPSA(maxiter=200, last_avg=5)
        solver = VQE(ansatz=ansatz,
                     optimizer=optimizer,
                     expectation=PauliExpectation(),
                     quantum_instance=QuantumInstance(
                         backend=backend,
                         seed_simulator=algorithm_globals.random_seed,
                         seed_transpiler=algorithm_globals.random_seed))

        gsc = GroundStateEigensolver(qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(result.total_energies[0], -1.138, places=2)
    def setUp(self):
        super().setUp()
        algorithm_globals.random_seed = 8
        try:
            self.driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 0.75',
                                      unit=UnitsType.ANGSTROM,
                                      charge=0,
                                      spin=0,
                                      basis='sto3g')
        except QiskitNatureError:
            self.skipTest('PYSCF driver does not appear to be installed')

        self.reference_energies = [-1.8427016, -1.8427016 + 0.5943372, -1.8427016 + 0.95788352,
                                   -1.8427016 + 1.5969296]
        self.qubit_converter = QubitConverter(JordanWignerMapper())
        self.electronic_structure_problem = ElectronicStructureProblem(self.driver)

        solver = NumPyEigensolver()
        self.ref = solver
        self.quantum_instance = QuantumInstance(BasicAer.get_backend('statevector_simulator'),
                                                seed_transpiler=90, seed_simulator=12)
Exemplo n.º 30
0
    def __init__(
        self,
        num_modals: List[int],
        qubit_converter: Optional[QubitConverter] = None,
    ) -> None:
        """
        Args:
            num_modals: Is a list defining the number of modals per mode. E.g. for a 3 modes system
                with 4 modals per mode num_modals = [4,4,4]
            qubit_converter: a QubitConverter instance. This argument is currently being ignored
                             because only a single use-case is supported at the time of release:
                             that of the :class:`DirectMapper`. However, for future-compatibility of
                             this functions signature, the argument has already been inserted.
        """
        # get the bitstring encoding initial state
        bitstr = vscf_bitstring(num_modals)

        # encode the bitstring in a `VibrationalOp`
        label = ['+' if bit else 'I' for bit in bitstr]
        bitstr_op = VibrationalOp(''.join(label),
                                  num_modes=len(num_modals),
                                  num_modals=num_modals)

        # map the `VibrationalOp` to a qubit operator
        if qubit_converter is not None:
            logger.warning(
                'The only supported `QubitConverter` is one with a `DirectMapper` as the mapper '
                'instance. However you specified %s as an input, which will be ignored until more '
                'variants will be supported.', str(qubit_converter))
        qubit_converter = QubitConverter(DirectMapper())
        qubit_op: PauliSumOp = qubit_converter.convert_match(bitstr_op)

        # construct the circuit
        qr = QuantumRegister(qubit_op.num_qubits, 'q')
        super().__init__(qr, name='VSCF')

        # add gates in the right positions
        for i, bit in enumerate(qubit_op.primitive.table.X[0]):
            if bit:
                self.x(i)