Basic usage of Qamuy SDK#

Install Qamuy Client SDK#

If you are running this notebook on Google Colaboratory, then install Qamuy Client SDK and login to Qamuy by running the following 2 cells. Otherwise, run commands in the following 2 cells on a terminal since they require input from standard input, which cannot be handled on Jupyter Notebook.

[ ]:
!python -m pip install qamuy-client --extra-index-url https://download.qamuy.qunasys.com/simple/

Import Qamuy#

To use Qamuy with SDK, please import Qamuy modules.

[2]:
import qamuy.chemistry as qy
from qamuy.client import Client

# You can fill in your e-mail address and password.
client = Client(email_address="YOUR_EMAIL_ADDRESS", password="YOUR_PASSWORD")

Create Input and Run Qamuy#

Create Input Object#

Create a Qamuy input object.

[3]:
setting = qy.QamuyChemistryInput()

A Qamuy input object has the following structure.

QamuyChemistryInput:

  • target_molecule

  • output_chemical_properties

  • post_hf_methods

  • quantum_device

  • mapping

  • solver

  • ansatz

  • cost_function

  • optimizer

Set Molecule#

Here is an example of water molecule. You can set molecular geometrical structure, basis set, active space, the number of excited state and so on.

[4]:
# H2O
atoms = ["H", "O", "H"]
coords = [
    [0.968877, 0.012358, 0.000000],
    [-0.019830, -0.025588, 0.000000],
    [-0.229801, 0.941311, 0.000000]
]

molecule = setting.target_molecule
molecule.geometry = qy.molecule_geometry(atoms, coords)
molecule.basis = "6-31g"
molecule.multiplicity = 1
molecule.num_excited_states = 0
molecule.cas = qy.cas(2, 2)

Set Chemical Properties to Be Calculated#

You can set the chemical Properties you want to calculate here. Qamuy supports electric dipole moment, electric transition dipole moment, nuclear gradient, Hessian, vibrational frequency and nonadiabtic coupling.

[5]:
# Electric dipole moment
setting.output_chemical_properties.append(
    qy.output_chemical_property(
        target="dipole_moment", states=[0]
    )
)

Set Classical Methods for Comparison#

Classical quantum chemistry calculation can be performed to do comparison. The available methods are MP2, CISD, CCSD, CASCI, CASSCF and FCI.

[6]:
setting.post_hf_methods.append(
    qy.PostHFMethod(type="CASCI")
)

Set Qubit Mapping#

JORDAN_WIGNER, BRAVYI_KITAEV and SYMMETRY_CONSERVING_BRAVYI_KITAEV are available in Qamuy.

[7]:
setting.mapping.type = "JORDAN_WIGNER"

Set VQE Type#

You can specify solver here. For computating elecronically excited state, SSVQE, MCVQE, VQD are available. You can also enable orbital optimizatin.

[8]:
setting.solver.type = "VQE"

Set Cost Function#

The penalty term can be set to confine the number of electron, spin muliplicity and overlap in VQD.

[9]:
# Set cost function
setting.cost_function.type = "SIMPLE"
setting.cost_function.s2_number_weight = 4.0
setting.cost_function.sz_number_weight = 4.0

Set Ansatz#

Set ansatz of electronic state. Note, you have set depth when you choose Symmetry Preserving, and trotter steps when you choose UCC and UCCSD.

[10]:
setting.ansatz.type = "SYMMETRY_PRESERVING"
setting.ansatz.depth = 4
setting.ansatz.use_random_initial_guess = True

Set Optimizer#

Set optimizer here.

[11]:
setting.optimizer.type = "BFGS"

Set Quantum Device#

By simply changing quantum device here, you can select state vector simulator, sampling sdimulator and real NISQ device.

[12]:
setting.quantum_device.type = "EXACT_SIMULATOR"

Run Job on Cloud#

Submit job to Qamuy Cloud.

[13]:
job = client.submit(setting)

Get Results and Plot#

Get Results#

Fetch the results from Qamuy cloud.

[14]:
results = client.wait_and_get_job_results([job])
output = results[0].output
[Parallel(n_jobs=-1)]: Using backend ThreadingBackend with 8 concurrent workers.
[Parallel(n_jobs=-1)]: Done   1 tasks      | elapsed:  1.5min
[Parallel(n_jobs=-1)]: Done   1 out of   1 | elapsed:  1.5min finished

You can extract the calculated result from the ouput as follows.

[15]:
q_result = output.molecule_result.quantum_device_result
c_result = output.molecule_result.post_hf_results[0]
vqe_log = q_result.vqe_log

Ouput Structure#

Qamuy output object has the following structure.

QamuyChemistryOutput:

  • input

  • molecule_result

    • hamiltonian_generation

    • hf_result

    • post_hf_results

      • post_hf_log

      • evaluated_properties

    • quantum_device

      • vqe_log

        • cost_hist

        • nfev

        • nit

        • opt_params

        • quantum_resources

          • circuit

          • estimated_execution_time

          • sampling

      • evaluated_properties

Plot Energy History#

You can plot the energy histroy easily.

[16]:
import qamuy.plot
fig, ax = qamuy.plot.plot_energy_history(output, state_label_map={0: "S0"})
../_images/_usecase_00_basics_54_0.png

Get Chemical Properties#

The structure of valuated_properties object is as follows.

[17]:
q_result.evaluated_properties
[17]:
[{'energy': {'values': [{'value': -75.9799236785195, 'state': 0, 'sample_std': 0.0}], 'metadata': {'elapsed_time': 0.0007705059999807418, 'success': True}}}, {'num_electrons': {'values': [{'value': 1.9999999999999996, 'state': 0}], 'metadata': {'elapsed_time': 0.0006290039999612418, 'success': True}}}, {'multiplicity': {'values': [{'value': 1.0000000000009266, 'state': 0}], 'metadata': {'elapsed_time': 0.0008784059999698002, 'success': True}}}, {'sz_number': {'values': [{'value': -1.7474910407599964e-13, 'state': 0}], 'metadata': {'elapsed_time': 0.000631903999988026, 'success': True}}}, {'dipole_moment': {'values': [{'value': [0.6539289242685531, 0.8437996784196387, 2.038928865996759e-06], 'sample_std': [0.0, 0.0, 0.0], 'state': 0}], 'metadata': {'elapsed_time': 0.0018270120000352108, 'success': True}}}]
[18]:
print("Energy:")
q_result.evaluated_properties[0].energy.values
Energy:
[18]:
[{'value': -75.9799236785195, 'state': 0, 'sample_std': 0.0}]
[19]:
print("Spin multiplicity:")
q_result.evaluated_properties[2].multiplicity.values
Spin multiplicity:
[19]:
[{'value': 1.0000000000009266, 'state': 0}]
[20]:
print("Dipole moment:")
q_result.evaluated_properties[4].dipole_moment.values
Dipole moment:
[20]:
[{'value': [0.6539289242685531, 0.8437996784196387, 2.038928865996759e-06], 'sample_std': [0.0, 0.0, 0.0], 'state': 0}]

Error Response#

In order to look a error response, let’s make a mistake.

Setup#

[22]:
from copy import deepcopy

setting_error = deepcopy(setting)

atoms = ["H", "Ge", "H"] #Change "O" to "Ge"
coords = [
    [0.968877, 0.012358, 0.000000],
    [-0.019830, -0.025588, 0.000000],
    [-0.229801, 0.941311, 0.000000]
]

molecule = setting_error.target_molecule
molecule.geometry = qy.molecule_geometry(atoms, coords)
molecule.basis = "6-31g"
molecule.multiplicity = 1
molecule.num_excited_states = 0
molecule.cas = qy.cas(2, 2)

Run Job#

[24]:
#run job
job = client.submit(setting_error)

# Get results
results = client.wait_and_get_job_results([job])
output = results[0].output
error = results[0].error['error']
[Parallel(n_jobs=-1)]: Using backend ThreadingBackend with 8 concurrent workers.
[Parallel(n_jobs=-1)]: Done   1 tasks      | elapsed:   42.1s
[Parallel(n_jobs=-1)]: Done   1 out of   1 | elapsed:   42.2s finished

Show Error#

The Error Response states “For Ge, There is no basis set of 6-31G”.

[25]:
print(error)
Traceback (most recent call last):
  File "/qamuy-cloud/.venv/lib/python3.7/site-packages/qamuy_cli/model_builder/molecular_model_builder.py", line 139, in build_molecular_model
    skip_scf=False,
  File "/qamuy-cloud/.venv/lib/python3.7/site-packages/qamuy_core/chemistry/qamuy_run_pyscf.py", line 35, in qamuy_run_pyscf
    ecp=mol_data.ecp,
  File "/qamuy-cloud/.venv/lib/python3.7/site-packages/qamuy_core/pyscf_wrappers/pyscf_wrappers.py", line 72, in compute_hf
    pyscf_mol.build(parse_arg=False)
  File "/qamuy-cloud/.venv/lib/python3.7/site-packages/pyscf/gto/mole.py", line 2346, in build
    self._basis = self.format_basis(_basis)
  File "/qamuy-cloud/.venv/lib/python3.7/site-packages/pyscf/gto/mole.py", line 2437, in format_basis
    return format_basis(basis_tab)
  File "/qamuy-cloud/.venv/lib/python3.7/site-packages/pyscf/gto/mole.py", line 422, in format_basis
    raise BasisNotFoundError('Basis not found for  %s' % symb)
pyscf.lib.exceptions.BasisNotFoundError: Basis not found for  Ge

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/qamuy-cloud/.venv/lib/python3.7/site-packages/qamuy_cli/qamuycore_executor.py", line 83, in execute
    params, mo_for_hamiltonian, init_oovqe_mo
  File "/qamuy-cloud/.venv/lib/python3.7/site-packages/qamuy_cli/qamuycore_executor.py", line 185, in _build_mol_model
    init_oovqe_mo,
  File "/qamuy-cloud/.venv/lib/python3.7/site-packages/qamuy_cli/model_builder/molecular_model_builder.py", line 142, in build_molecular_model
    raise QamuyCalculationError("Molecular orbital building failed.") from e
qamuy_cli.exceptions.QamuyCalculationError: Molecular orbital building failed.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/qamuy-cloud/.venv/lib/python3.7/site-packages/qamuy_cli/__main__.py", line 125, in main
    s3_folder,
  File "/qamuy-cloud/.venv/lib/python3.7/site-packages/qamuy_cli/utils/run.py", line 34, in run_all
    s3_folder,
  File "/qamuy-cloud/.venv/lib/python3.7/site-packages/qamuy_cli/utils/run.py", line 65, in run_compute
    s3_folder=s3_folder,
  File "/qamuy-cloud/.venv/lib/python3.7/site-packages/qamuy_cli/qamuycore_executor.py", line 86, in execute
    raise QamuyCalculationError("Build molecular model failed") from e
qamuy_cli.exceptions.QamuyCalculationError: Build molecular model failed

Sampling Simulator#

Prepare Input#

For changing to sampling simulator is easy, just change quantum device.

[26]:
setting_sampling = deepcopy(setting)
setting_sampling.quantum_device.type = "SAMPLING_SIMULATOR"
setting_sampling.observable_grouping.type = "BITWISE_COMMUTING"
setting_sampling.sampling_strategy.type = "WEIGHTED"
setting_sampling.sampling_strategy.num_total_shots = 1e6
setting_sampling.sampling_strategy.shot_unit = 1

Run Job and Plot#

Run job and plot are same with the case of state vector simulator.

[33]:
# run job
job = client.submit(setting_sampling)

# Get results
results = client.wait_and_get_job_results([job])
output = results[0].output

# Extract results
q_result = output.molecule_result.quantum_device_result
c_result = output.molecule_result.post_hf_results[0]
vqe_log = q_result.vqe_log
[Parallel(n_jobs=-1)]: Using backend ThreadingBackend with 8 concurrent workers.
[Parallel(n_jobs=-1)]: Done   1 tasks      | elapsed:   37.0s
[Parallel(n_jobs=-1)]: Done   1 out of   1 | elapsed:   37.0s finished
[34]:
import qamuy.plot
fig, ax = qamuy.plot.plot_energy_history(output, state_label_map={0: "S0"})
../_images/_usecase_00_basics_77_0.png

Potential Energy Curve#

Setup#

[29]:
distance_list = [0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.2, 1.6, 2.]

jobs = []
for distance in distance_list:
    new_input = deepcopy(setting)
    new_input.target_molecule.geometry = qy.molecule_geometry(["H", "H"], [[0.0, 0.0, - distance / 2], [0.0, 0.0, distance / 2]])
    jobs.append(client.submit(new_input))
[30]:
results = client.wait_and_get_job_results(jobs)
outputs = [res.output for res in results]
[Parallel(n_jobs=-1)]: Using backend ThreadingBackend with 8 concurrent workers.
[Parallel(n_jobs=-1)]: Done   2 out of  11 | elapsed:   21.3s remaining:  1.6min
[Parallel(n_jobs=-1)]: Done   4 out of  11 | elapsed:   31.7s remaining:   55.5s
[Parallel(n_jobs=-1)]: Done   6 out of  11 | elapsed:   36.9s remaining:   30.8s
[Parallel(n_jobs=-1)]: Done   8 out of  11 | elapsed:   36.9s remaining:   13.9s
[Parallel(n_jobs=-1)]: Done  11 out of  11 | elapsed:   47.8s finished
[31]:
energy_list=[output.molecule_result.quantum_device_result.evaluated_properties[0].energy.values[0].value for output in outputs]
[32]:
import matplotlib.pyplot as plt

plt.plot(distance_list,energy_list, "o-")
plt.xlabel("Bond length [$\AA$]")
plt.ylabel("Energy [Ha]")
plt.title("Potential Energy Curve for H2")
plt.show()
../_images/_usecase_00_basics_83_0.png