diff --git a/README.rst b/README.rst index 7f6793250..24d0c7a53 100644 --- a/README.rst +++ b/README.rst @@ -7,6 +7,9 @@ .. raw:: html

+ + maintainer + license @@ -19,9 +22,7 @@ .. |build| image:: https://github.com/goodchemistryco/Tangelo/actions/workflows/continuous_integration.yml/badge.svg :target: https://github.com/goodchemistryco/Tangelo/actions/workflows/continuous_integration.yml -Tangelo is an open-source Python package maintained by `SandboxAQ `_, focusing on the development of quantum chemistry simulation workflows on quantum computers. It was developed as an engine to accelerate research, and takes advantage of other popular frameworks to harness the innovation in our field. - -Tangelo is an open-source Python package maintained by `Good Chemistry Company `_, focusing on the development of quantum chemistry simulation workflows on quantum computers. It was developed as an engine to accelerate research, and leverages other popular frameworks to harness the innovation in our field. +Tangelo is an open-source Python package maintained by `Good Chemistry Company `_, focusing on the development of quantum chemistry simulation workflows on quantum computers. It was developed as an engine to accelerate research, and takes advantage of other popular frameworks to harness the innovation in our field. ------------- @@ -29,6 +30,8 @@ Tangelo is an open-source Python package maintained by `Good Chemistry Company <

Tutorials +  ·  + Features  ·  Docs  ·  @@ -37,19 +40,13 @@ Tangelo is an open-source Python package maintained by `Good Chemistry Company < ------------- -This package provides a growing collection of algorithms and toolboxes, including problem decomposition, to support quantum algorithms R&D and the design of successful experiments on quantum devices. Tangelo is backend-agnostic, so that users can write code once and experiment with current and future platforms with minimal changes. Tangelo is capable to perform quantum experiments that led to publications in scientific journals, co-authored by professionals from the chemical industry and quantum hardware manufacturers. +This package provides a growing collection of algorithms and toolboxes to support quantum algorithms R&D and the design of successful experiments on quantum devices. Tangelo is backend-agnostic, which means users can write quantum algortihms once and run their calculations on current and future platforms with minimal changes. Tangelo is capable to perform quantum experiments that led to publications in scientific journals, co-authored by professionals from the chemical industry and quantum hardware manufacturers. -

- Tutorials -  ·  - Features -  ·  - Docs -  ·  - Blog -

+.. raw:: html -------------- +

+ tangelo_workflow +

.. |curve| image:: ./docs/source/_static/img/curve_dmet_qcc.png :width: 400 @@ -92,7 +89,7 @@ Optional dependencies: Quantum Simulators and Classical Quantum Chemistry ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Tangelo enables users to target various backends. In particular, it integrates quantum circuit simulators such as ``qulacs``\ , ``qiskit``\ , ``cirq``, among others. We leave it to you to install the packages of your choice, and refer to their own documentation. Most packages can be installed through pip or conda easily. -Tangelo can be used without having a classical quantum chemistry package installed but many chemistry algorithms need one. The two quantum chemistry packages that are natively supported are `PySCF `_ and `Psi4 `_, which can be installed through pip or conda. It is possible to plug in your own `IntegralSolver `_ or pre-computed integrals too. +Tangelo can be used without having a classical quantum chemistry package installed but many chemistry algorithms need one. The two quantum chemistry packages that are natively supported are `PySCF `_ and `Psi4 `_, which can be installed through pip or conda. It is possible to plug in your own pre-computed integrals and other chemistry calculations done with the tools of your choice, or your own compute backend for executing quantum algorithms. Optional: environment variables ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tangelo/_version.py b/tangelo/_version.py index 3847f522c..8114e674e 100644 --- a/tangelo/_version.py +++ b/tangelo/_version.py @@ -14,4 +14,4 @@ """ Define version number here. It is read in setup.py, and bumped automatically when using the new release Github action. """ -__version__ = "0.4.1" +__version__ = "0.4.2" diff --git a/tangelo/algorithms/projective/iqpe.py b/tangelo/algorithms/projective/iqpe.py index 7e955192c..03ae9f00e 100644 --- a/tangelo/algorithms/projective/iqpe.py +++ b/tangelo/algorithms/projective/iqpe.py @@ -1,4 +1,4 @@ -# Copyright SandboxAQ 2021-2024. +# Copyright 2023 Good Chemistry Company. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tangelo/algorithms/projective/qpe.py b/tangelo/algorithms/projective/qpe.py index db78fc208..0a754a7f7 100644 --- a/tangelo/algorithms/projective/qpe.py +++ b/tangelo/algorithms/projective/qpe.py @@ -94,10 +94,17 @@ def __init__(self, opt_dict): if len(copt_dict) > 0: raise KeyError(f"The following keywords are not supported in {self.__class__.__name__}: \n {copt_dict.keys()}") + # If nothing is provided raise and Error: + if not (bool(self.molecule) or bool(self.qubit_hamiltonian) or isinstance(self.unitary, (unitary.Unitary, Circuit))): + raise ValueError(f"A Molecule or a QubitOperator or a Unitary object/Circuit must be provided in {self.__class__.__name__}") + # Raise error/warnings if input is not as expected. Only a single input - # must be provided to avoid conflicts. - if not (bool(self.molecule) ^ bool(self.qubit_hamiltonian)): - raise ValueError(f"A molecule OR qubit Hamiltonian object must be provided when instantiating {self.__class__.__name__}.") + if (bool(self.molecule) and bool(self.qubit_hamiltonian)): + raise ValueError(f"Both a molecule and qubit Hamiltonian can not be provided when instantiating {self.__class__.__name__}.") + if isinstance(self.unitary, Circuit) and bool(self.qubit_hamiltonian): + raise ValueError(f"Both a qubit Hamiltonian and a circuit defining the unitary can not be provided in {self.__class__.__name__}.") + if isinstance(self.unitary, (Circuit, unitary.Unitary)) and bool(self.molecule): + raise Warning("The molecule is only being used to generate the reference state. The unitary is being used for the QPE.") if self.ref_state is not None: if isinstance(self.ref_state, Circuit): @@ -150,7 +157,7 @@ def build(self): if isinstance(self.unitary, BuiltInUnitary): self.unitary = self.unitary.value(self.qubit_hamiltonian, **self.unitary_options) elif not isinstance(self.unitary, unitary.Unitary): - raise TypeError(f"Invalid ansatz dataype. Expecting a custom Unitary (Unitary class).") + raise TypeError("Invalid ansatz dataype. Expecting a custom Unitary (Unitary class).") # Quantum circuit simulation backend options self.backend = get_backend(**self.backend_options) diff --git a/tangelo/algorithms/projective/tests/test_qpe.py b/tangelo/algorithms/projective/tests/test_qpe.py index 5925ecfba..63d93ea8b 100644 --- a/tangelo/algorithms/projective/tests/test_qpe.py +++ b/tangelo/algorithms/projective/tests/test_qpe.py @@ -76,7 +76,7 @@ def test_simulate_h2_circuit(self): "n_electrons": mol_H2_sto3g.n_active_electrons}) # Test supplying circuit and applying QPE controls to only gates marked as variational - qpe_options = {"qubit_hamiltonian": qu_op, "unitary": unit_circ, "size_qpe_register": 8, "ref_state": ref_circ, + qpe_options = {"unitary": unit_circ, "size_qpe_register": 8, "ref_state": ref_circ, "backend_options": {"target": "qulacs"}, "unitary_options": {"control_method": "variational"}} qpe_solver = QPESolver(qpe_options) qpe_solver.build() @@ -86,7 +86,7 @@ def test_simulate_h2_circuit(self): self.assertAlmostEqual(energy, -(-1.13727-qu_op.constant), delta=1e-3) # Test supplying circuit with QPE controls added to every gate. - qpe_options = {"qubit_hamiltonian": qu_op, "unitary": unit_circ, "size_qpe_register": 8, "ref_state": ref_circ, + qpe_options = {"unitary": unit_circ, "size_qpe_register": 8, "ref_state": ref_circ, "backend_options": {"target": "qulacs"}, "unitary_options": {"control_method": "all"}} qpe_solver = QPESolver(qpe_options) qpe_solver.build() diff --git a/tangelo/linq/circuit.py b/tangelo/linq/circuit.py index 00e57f5f9..df23f933f 100644 --- a/tangelo/linq/circuit.py +++ b/tangelo/linq/circuit.py @@ -426,29 +426,6 @@ def simplify(self, max_cycles=100, param_threshold=1e-3, remove_qubits=False): remove_qubits=remove_qubits) self.__dict__ = opt_circuit.__dict__ - def merge_rotations(self): - """ Convenience method to merge compatible rotations applied successively on identical qubits indices. - The operation is done in-place and alters the input circuit. - """ - opt_circuit = merge_rotations(self) - self.__dict__ = opt_circuit.__dict__ - - def simplify(self, max_cycles=100, param_threshold=1e-3, remove_qubits=False): - """ Convenience method to simplify gates in a circuit, by repeating a set of simple passes - until no further changes occurs, or a maximum number of cycles has been reached. - - Args: - max_cycles (int): Optional, maximum number of cycles to perform - param_threshold (float): Optional, max absolute value to consider a rotation - as small enough to be discarded - remove_qubits (bool): Optional, remove qubit with no operations assigned left - """ - - opt_circuit = simplify(self, - max_cycles=max_cycles, param_threshold=param_threshold, - remove_qubits=remove_qubits) - self.__dict__ = opt_circuit.__dict__ - def controlled_measurement_op(self, measure): """Call the object self._cmeasure_control and return the next circuit to apply.""" if callable(self._cmeasure_control): diff --git a/tangelo/problem_decomposition/tests/incremental/data/1332907003284964215.h5 b/tangelo/problem_decomposition/tests/incremental/data/1332907003284964215.h5 deleted file mode 100644 index 74786f3d5..000000000 Binary files a/tangelo/problem_decomposition/tests/incremental/data/1332907003284964215.h5 and /dev/null differ diff --git a/tangelo/problem_decomposition/tests/incremental/data/13910068485509107083.h5 b/tangelo/problem_decomposition/tests/incremental/data/13910068485509107083.h5 deleted file mode 100644 index 1202ee4e9..000000000 Binary files a/tangelo/problem_decomposition/tests/incremental/data/13910068485509107083.h5 and /dev/null differ diff --git a/tangelo/problem_decomposition/tests/incremental/data/2797394433445874430.h5 b/tangelo/problem_decomposition/tests/incremental/data/2797394433445874430.h5 deleted file mode 100644 index b5c0f6cc7..000000000 Binary files a/tangelo/problem_decomposition/tests/incremental/data/2797394433445874430.h5 and /dev/null differ diff --git a/tangelo/problem_decomposition/tests/incremental/data/5397298052826288002.h5 b/tangelo/problem_decomposition/tests/incremental/data/5397298052826288002.h5 deleted file mode 100644 index 50147a526..000000000 Binary files a/tangelo/problem_decomposition/tests/incremental/data/5397298052826288002.h5 and /dev/null differ diff --git a/tangelo/problem_decomposition/tests/incremental/data/9251772583352486736.h5 b/tangelo/problem_decomposition/tests/incremental/data/9251772583352486736.h5 deleted file mode 100644 index fce028b3f..000000000 Binary files a/tangelo/problem_decomposition/tests/incremental/data/9251772583352486736.h5 and /dev/null differ diff --git a/tangelo/problem_decomposition/tests/incremental/data/9588529898904111370.h5 b/tangelo/problem_decomposition/tests/incremental/data/9588529898904111370.h5 deleted file mode 100644 index d0eb4a164..000000000 Binary files a/tangelo/problem_decomposition/tests/incremental/data/9588529898904111370.h5 and /dev/null differ diff --git a/tangelo/problem_decomposition/tests/incremental/test_ifci_helper.py b/tangelo/problem_decomposition/tests/incremental/test_ifci_helper.py index bb0c1cdc9..d1ce1dbf4 100644 --- a/tangelo/problem_decomposition/tests/incremental/test_ifci_helper.py +++ b/tangelo/problem_decomposition/tests/incremental/test_ifci_helper.py @@ -1,4 +1,4 @@ -# Copyright SandboxAQ 2021-2024. +# Copyright 2023 Good Chemistry Company. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tangelo/problem_decomposition/tests/incremental/test_mifno_helper.py b/tangelo/problem_decomposition/tests/incremental/test_mifno_helper.py index d7ee8ce98..933c3ac48 100644 --- a/tangelo/problem_decomposition/tests/incremental/test_mifno_helper.py +++ b/tangelo/problem_decomposition/tests/incremental/test_mifno_helper.py @@ -20,7 +20,7 @@ pwd_this_test = os.path.dirname(os.path.abspath(__file__)) data_folder = os.path.join(pwd_this_test, "data") -mi_results = os.path.join(data_folder, "BeH2_STO3G_MIFNO_HBCI.json") +mi_results = os.path.join(data_folder, "BeH2_CCPVDZ_MIFNO_HBCI/full_results_186184445859680125.log") with open(mi_results, "r") as f: mi_object = json.loads("\n".join(f.readlines()[1:])) @@ -30,14 +30,14 @@ class MIFNOHelperTest(unittest.TestCase): def setUp(self): - self.e_tot = -15.5951183 - self.e_corr = -0.0350199 + self.e_tot = -15.83647358459995 + self.e_corr = -0.06915435696141081 self.e_mf = self.e_tot - self.e_corr def test_init_from_file(self): """Verify initialization with a json file.""" - beh2_mifno = MIFNOHelper(mifno_log_file=mi_results) + beh2_mifno = MethodOfIncrementsHelper(log_file=mi_results) self.assertAlmostEqual(beh2_mifno.e_tot, self.e_tot) self.assertAlmostEqual(beh2_mifno.e_corr, self.e_corr) @@ -49,7 +49,7 @@ def test_init_from_file(self): def test_init_from_dict(self): """Verify initialization with a dict object.""" - beh2_mifno = MIFNOHelper(mifno_full_result=mi_object) + beh2_mifno = MethodOfIncrementsHelper(full_result=mi_object) self.assertAlmostEqual(beh2_mifno.e_tot, self.e_tot) self.assertAlmostEqual(beh2_mifno.e_corr, self.e_corr) @@ -61,7 +61,7 @@ def test_init_from_dict(self): def test_fragment_ids(self): """Verify whether fragment_ids property returns all the fragment ids.""" - beh2_mifno = MIFNOHelper(mifno_full_result=mi_object) + beh2_mifno = MethodOfIncrementsHelper(full_result=mi_object) frag_ids = beh2_mifno.fragment_ids self.assertEqual(frag_ids, ["(0,)", "(1,)", "(2,)", "(0, 1)", "(0, 2)", "(1, 2)"]) @@ -69,8 +69,7 @@ def test_fragment_ids(self): def test_mi_summation(self): """Verify that the energy can be recomputed with the incremental method.""" - beh2_mifno = MIFNOHelper(mifno_full_result=mi_object) - + beh2_mifno = MethodOfIncrementsHelper(full_result=mi_object) e_mi = beh2_mifno.mi_summation() self.assertAlmostEqual(e_mi, beh2_mifno.e_tot) diff --git a/tangelo/toolboxes/molecular_computation/fno.py b/tangelo/toolboxes/molecular_computation/fno.py index 9b1ac0e0d..1dfcfb5eb 100644 --- a/tangelo/toolboxes/molecular_computation/fno.py +++ b/tangelo/toolboxes/molecular_computation/fno.py @@ -1,4 +1,4 @@ -# Copyright SandboxAQ 2021-2024. +# Copyright 2023 Good Chemistry Company. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tangelo/toolboxes/molecular_computation/integral_solver_pyscf.py b/tangelo/toolboxes/molecular_computation/integral_solver_pyscf.py index a6bedb6f7..56ad10256 100644 --- a/tangelo/toolboxes/molecular_computation/integral_solver_pyscf.py +++ b/tangelo/toolboxes/molecular_computation/integral_solver_pyscf.py @@ -407,10 +407,7 @@ def compute_mean_field(self, sqmol): raise ValueError("Hartree-Fock calculation did not converge") if sqmol.symmetry: - sqmol.mo_symm_ids = list(self.symm.label_orb_symm(sqmol.mean_field.mol, sqmol.mean_field.mol.irrep_id, - sqmol.mean_field.mol.symm_orb, sqmol.mean_field.mo_coeff)) - irrep_map = {i: s for s, i in zip(molecule.irrep_name, molecule.irrep_id)} - sqmol.mo_symm_labels = [irrep_map[i] for i in sqmol.mo_symm_ids] + self.assign_mo_coeff_symmetries(sqmol) else: sqmol.mo_symm_ids = None sqmol.mo_symm_labels = None diff --git a/tangelo/toolboxes/molecular_computation/molecule.py b/tangelo/toolboxes/molecular_computation/molecule.py index 07d9546cd..0fa15ba84 100644 --- a/tangelo/toolboxes/molecular_computation/molecule.py +++ b/tangelo/toolboxes/molecular_computation/molecule.py @@ -337,6 +337,8 @@ def mo_coeff(self, new_mo_coeff): self.solver.mo_coeff = new_mo_coeff if hasattr(self.solver, "modify_solver_mo_coeff"): self.solver.modify_solver_mo_coeff(self) + if hasattr(self.solver, "assign_mo_coeff_symmetries") and self.symmetry: + self.solver.assign_mo_coeff_symmetries(self) def _get_fermionic_hamiltonian(self, mo_coeff=None): """This method returns the fermionic hamiltonian. It written to take diff --git a/tangelo/toolboxes/molecular_computation/tests/test_fno.py b/tangelo/toolboxes/molecular_computation/tests/test_fno.py index 45e690876..72685a700 100644 --- a/tangelo/toolboxes/molecular_computation/tests/test_fno.py +++ b/tangelo/toolboxes/molecular_computation/tests/test_fno.py @@ -1,4 +1,4 @@ -# Copyright SandboxAQ 2021-2024. +# Copyright 2023 Good Chemistry Company. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License.