Skip to content

Commit

Permalink
Refactor simulator (#213)
Browse files Browse the repository at this point in the history
* Define SimulatorBase class, which can be used to define target-specific classes.
* Simulator is now a factory function and not a class
* We provide some built-in backends, and support user-defined backends. This can also support quantum hardware as backends.
  • Loading branch information
JamesB-1qbit authored Oct 13, 2022
1 parent c5061e7 commit 25d5a58
Show file tree
Hide file tree
Showing 17 changed files with 957 additions and 553 deletions.
7 changes: 4 additions & 3 deletions examples/linq/1.the_basics.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -329,9 +329,10 @@
}
],
"source": [
"from tangelo.linq import SUPPORTED_GATES\n",
"from tangelo.linq import get_supported_gates\n",
"\n",
"for backend, gates in SUPPORTED_GATES.items():\n",
"supported_gates = get_supported_gates()\n",
"for backend, gates in supported_gates.items():\n",
" print(f'{backend} : {gates}')"
]
},
Expand Down Expand Up @@ -844,7 +845,7 @@
"# Option2: Assume quantum circuit simulation was performed separately (by this package or different services)\n",
"freqs, _ = sim.simulate(c) # circuit c must be consistent with operator, regarding measurement along non-z axes\n",
"term, coef = tuple(op.terms.items())[0] # This yields ((0, 'Z'),), 1.0\n",
"expval2 = coef * Simulator.get_expectation_value_from_frequencies_oneterm(term, freqs)\n",
"expval2 = coef * sim.get_expectation_value_from_frequencies_oneterm(term, freqs)\n",
"print(expval2)"
]
},
Expand Down
15 changes: 10 additions & 5 deletions examples/linq/2.qpu_connection.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -767,24 +767,24 @@
}
],
"source": [
"from tangelo.linq import Simulator\n",
"from tangelo.linq import get_expectation_value_from_frequencies_oneterm\n",
"from tangelo.linq.helpers.circuits.measurement_basis import pauli_string_to_of\n",
"\n",
"# Rescale counts to obtain frequency histogram\n",
"freqs = {k:v/100 for k,v in counts.items()}\n",
"print(f\"Frequencies: {freqs}\")\n",
"\n",
"# Compute expectation value for ZZ operator\n",
"exp_ZZ = Simulator.get_expectation_value_from_frequencies_oneterm(pauli_string_to_of(\"ZZ\"), freqs)\n",
"exp_ZZ = get_expectation_value_from_frequencies_oneterm(pauli_string_to_of(\"ZZ\"), freqs)\n",
"print(f\"Expectation value for ZZ operator {exp_ZZ}\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "main_release0.3.1",
"display_name": "Python 3.9.7 64-bit ('qsdkmain': venv)",
"language": "python",
"name": "main_release0.3.1"
"name": "python3"
},
"language_info": {
"codemirror_mode": {
Expand All @@ -796,7 +796,12 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
"version": "3.9.10"
},
"vscode": {
"interpreter": {
"hash": "95050af2697fca56ed7491a4fb0b04c1282c0de0a7e0a7cacd318a8297b0b1d8"
}
}
},
"nbformat": 4,
Expand Down
15 changes: 14 additions & 1 deletion tangelo/algorithms/variational/tests/test_vqe_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import numpy as np

from tangelo.linq import Simulator
from tangelo.helpers.utils import installed_backends
from tangelo.linq.target import QiskitSimulator
from tangelo.algorithms import BuiltInAnsatze, VQESolver
from tangelo.molecule_library import mol_H2_sto3g, mol_H4_sto3g, mol_H4_cation_sto3g, mol_NaH_sto3g, mol_H4_sto3g_symm
from tangelo.toolboxes.ansatz_generator.uccsd import UCCSD
Expand Down Expand Up @@ -197,9 +199,10 @@ def test_simulate_vsqs_h2(self):
energy = vqe_solver.simulate()
self.assertAlmostEqual(energy, -1.137270, delta=1e-4)

@unittest.skipIf("qiskit" not in installed_backends, "Test Skipped: Backend not available \n")
def test_simulate_h2_qiskit(self):
"""Run VQE on H2 molecule, with UCCSD ansatz, JW qubit mapping, initial
parameters, exact qiskit simulator.
parameters, exact qiskit simulator. Both string and class input.
"""

backend_options = {"target": "qiskit", "n_shots": None, "noise_model": None}
Expand All @@ -212,6 +215,16 @@ def test_simulate_h2_qiskit(self):

self.assertAlmostEqual(energy, -1.13727042117, delta=1e-6)

backend_options = {"target": QiskitSimulator, "n_shots": None, "noise_model": None}
vqe_options = {"molecule": mol_H2_sto3g, "ansatz": BuiltInAnsatze.UCCSD, "qubit_mapping": "jw",
"initial_var_params": [6.28531447e-06, 5.65431626e-02], "verbose": True,
"backend_options": backend_options}
vqe_solver = VQESolver(vqe_options)
vqe_solver.build()
energy = vqe_solver.simulate()

self.assertAlmostEqual(energy, -1.13727042117, delta=1e-6)

def test_simulate_h4(self):
"""Run VQE on H4 molecule, with UCCSD ansatz, JW qubit mapping, initial
parameters, exact simulator.
Expand Down
11 changes: 4 additions & 7 deletions tangelo/helpers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import os
import sys
from importlib import util


class HiddenPrints:
Expand All @@ -34,13 +35,9 @@ def __exit__(self, exc_type, exc_val, exc_tb):


def is_package_installed(package_name):
try:
exec(f"import {package_name}")
# DEBUG print(f'{package_name:16s} :: found')
return True
except ModuleNotFoundError:
# DEBUG print(f'{package_name:16s} :: not found')
return False
"""Check if module is installed without importing."""
spam_spec = util.find_spec(package_name)
return spam_spec is not None


# List all backends and statevector ones supported by Simulator class
Expand Down
1 change: 1 addition & 0 deletions tangelo/linq/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@
from .gate import *
from .circuit import Circuit, stack, remove_small_rotations, remove_redundant_gates
from .translator import *
from .simulator_base import get_expectation_value_from_frequencies_oneterm
from .simulator import Simulator, backend_info
Loading

0 comments on commit 25d5a58

Please sign in to comment.