Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quantum Chemistry Notebook Documentation #30

Merged
merged 21 commits into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
385ac86
Updated documentation content for quantum chemistry notebook about in…
JonhasSC Apr 4, 2024
9d9e526
Added additional information regarding HF, measuring activation energ…
JonhasSC Apr 11, 2024
ad3cf22
changing name of xyz file from Co4O4 to Co2O9H12
JonhasSC Apr 16, 2024
42fa579
improved documentation for quantum chemistry notebook
JonhasSC Apr 16, 2024
18eaf22
Updated pylint badge
github-actions[bot] Apr 19, 2024
35c1b93
added a references section in the quantum chemistry notebook
JonhasSC Apr 22, 2024
ac35182
pylint fixes for algo_utils
JonhasSC Apr 22, 2024
6db8fc7
some pylint fixes for hamiltoniain_utils
JonhasSC Apr 22, 2024
bc1a8d6
import grouping pylint fixes
JonhasSC Apr 22, 2024
04572be
some pylint changes for utils.py
JonhasSC Apr 22, 2024
28a3edc
Updated pylint badge
github-actions[bot] Apr 22, 2024
5e247fd
merged with dev
JonhasSC Apr 25, 2024
8ccbe56
Added a sentence to clarify the notebooks computational targets
JonhasSC Apr 25, 2024
cf60d31
reran ap notebook for grabbing re
JonhasSC Apr 25, 2024
8827bc8
made changes to specify how the scaling factor is defined
JonhasSC Apr 25, 2024
69e8ae0
reran notebook and assured resource estimates follow standard and mak…
JonhasSC Apr 25, 2024
4516353
Updated pylint badge
github-actions[bot] Apr 25, 2024
16ca5c2
fixed typo for nb
JonhasSC Apr 25, 2024
ff59fff
adding clarified paragraph given feedback
JonhasSC Apr 27, 2024
c6a01aa
fixed typos
JonhasSC Apr 29, 2024
fb81a3d
rewrote active space comment
JonhasSC Apr 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
![pylint](https://img.shields.io/badge/PyLint-9.08-yellow?logo=python&logoColor=white)
![pylint](https://img.shields.io/badge/PyLint-9.60-yellow?logo=python&logoColor=white)
# Quantum Computing Application Specifications

Documentation of Applications for Quantum Computers
Expand Down
File renamed without changes.
File renamed without changes.
770 changes: 641 additions & 129 deletions notebooks/PhotosynthesisExample.ipynb

Large diffs are not rendered by default.

20 changes: 13 additions & 7 deletions src/qca/utils/algo_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,24 @@
import random
import numpy as np
import networkx as nx

from cirq import Circuit
from openfermion import count_qubits
from cirq.contrib import qasm_import
from pyLIQTR.utils.Hamiltonian import Hamiltonian

from openfermion import count_qubits
from openfermion.ops.operators import QubitOperator
from openfermion.circuits import trotter_steps_required, error_bound
from openfermion.circuits.trotter_exp_to_qgates import trotterize_exp_qubop_to_qasm

from pyLIQTR.utils.Hamiltonian import Hamiltonian
from pyLIQTR.utils.utils import open_fermion_to_qasm
from pyLIQTR.circuits.qsp import generate_QSP_circuit
from pyLIQTR.utils.qsp_helpers import print_to_openqasm
from openfermion.circuits import trotter_steps_required, error_bound
from qca.utils.utils import circuit_estimate, estimate_cpt_resources
from pyLIQTR.gate_decomp.cirq_transforms import clifford_plus_t_direct_transform
from openfermion.circuits.trotter_exp_to_qgates import trotterize_exp_qubop_to_qasm
from pyLIQTR.phase_factors.fourier_response.fourier_response import Angler_fourier_response

from qca.utils.utils import circuit_estimate, estimate_cpt_resources

def estimate_qsp(
pyliqtr_hamiltonian: Hamiltonian,
evolution_time:float,
Expand Down Expand Up @@ -58,7 +62,9 @@ def find_hamiltonian_ordering(of_hamiltonian: QubitOperator) -> list:
#ordering hamiltonian terms by performing edge coloring to make optimal trotter ordering
#assuming that any 2 body interactions are ZZ
sorted_terms = sorted(list(of_hamiltonian.terms.keys()))
sorted_terms.sort(key=lambda x: len(x) * 100 + ord(x[0][1])) #Z and X get translated to 90 and 88 respectively, multiplying by 100 ensures interacting term weight is considered

#Z and X get translated to 90 and 88 respectively, multiplying by 100 ensures interacting term weight is considered
sorted_terms.sort(key=lambda x: len(x) * 100 + ord(x[0][1]))
one_body_terms_ordered = list(filter(lambda x: len(x) == 1, sorted_terms))
two_body_terms = list(filter(lambda x: len(x) == 2, sorted_terms))

Expand All @@ -77,7 +83,7 @@ def find_hamiltonian_ordering(of_hamiltonian: QubitOperator) -> list:
two_body_terms[i] = term

two_body_terms.sort(key=lambda x: x[2])
two_body_terms_ordered = list()
two_body_terms_ordered = []
for (i,term) in enumerate(two_body_terms):
new_item = (term[0],term[1])
two_body_terms_ordered.append(new_item)
Expand Down
21 changes: 13 additions & 8 deletions src/qca/utils/hamiltonian_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def nx_longitudinal_ising_terms(graph,p,magnitude=1) -> list[tuple[str, float]]:
n = len(graph.nodes)
for n1, n2 in graph.edges:
weight = magnitude if random.random() < p else -magnitude
curr_hamil_string = n * 'I'
curr_hamil_string = n * 'I'
for idx in range(len(graph)):
if idx == n1 or idx == n2:
curr_hamil_string = f'{curr_hamil_string[:idx]}Z{curr_hamil_string[idx+1:]}'
Expand All @@ -146,7 +146,7 @@ def nx_transverse_ising_terms(graph: Graph,p,magnitude=0.1) -> list[tuple[str, f
n = len(graph)
for idx in range(n):
w = magnitude if random.random() < p else -magnitude
curr_hamil_string = n * 'I'
curr_hamil_string = n * 'I'
for k in range(n):
if idx == k:
curr_hamil_string = f'{curr_hamil_string[:idx]}X{curr_hamil_string[idx+1:]}'
Expand All @@ -161,14 +161,19 @@ def nx_triangle_lattice(lattice_size: int) -> Graph:
graph.add_edge((i,j),(i+1,j+1))
return graph

def generate_triangle_hamiltonian(lattice_size: int, longitudinal_weight_prob:float=0.5, transverse_weight_prob:float=1):
def generate_triangle_hamiltonian(lattice_size: int,
longitudinal_weight_prob:float=0.5,
transverse_weight_prob:float=1):
graph = nx_triangle_lattice(lattice_size)
graph = flatten_nx_graph(graph)
H_transverse = nx_transverse_ising_terms(graph, transverse_weight_prob)
H_longitudinal = nx_longitudinal_ising_terms(graph, longitudinal_weight_prob)
return H_transverse, H_longitudinal

def generate_square_hamiltonian(lattice_size: int, dim:int, longitudinal_weight_prob:float=0.5, transverse_weight_prob:float=1):
def generate_square_hamiltonian(lattice_size: int,
dim:int,
longitudinal_weight_prob:float=0.5,
transverse_weight_prob:float=1):
dimensions = (lattice_size, lattice_size) if dim == 2 else (lattice_size, lattice_size, lattice_size)
graph = grid_graph(dim=dimensions)
graph = flatten_nx_graph(graph)
Expand Down Expand Up @@ -196,20 +201,20 @@ def assign_hexagon_labels(graph:Graph, x:str='X', y:str='Y', z:str='Z'):
if r2 - r1 < 0 or c2 - c1 < 0:
r1, r2 = r2, r1
c1, c2 = c2, c1

# now that they are ordered correctly, we can assign labels
label = ''
if c1 == c2:
label = z
# You can differentiate X and Y labels based off nx's node label parity
elif (((r1 % 2) + (c1 % 2)) % 2 == 0):
elif ((r1 % 2) + (c1 % 2)) % 2 == 0:
label = y
else:
label = x

graph[n1][n2]['label'] = label

def assign_directional_triangular_labels(g:Graph, lattice_size:int) -> None:
def assign_directional_triangular_labels(g:Graph, lattice_size:int) -> None:
for i in range(lattice_size - 1):
for j in range(lattice_size - 1):
g[(i,j)][(i+1,j)]['label'] = 'Z'
Expand Down
49 changes: 35 additions & 14 deletions src/qca/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@
import re
import json
import time
import pandas as pd
from statistics import median

import pandas as pd

import matplotlib.pyplot as plt
from pyLIQTR.utils.utils import count_T_gates

from cirq import Circuit, AbstractCircuit

from pyLIQTR.utils.utils import count_T_gates
from pyLIQTR.utils.qsp_helpers import circuit_decompose_once, print_to_openqasm
from pyLIQTR.gate_decomp.cirq_transforms import clifford_plus_t_direct_transform

Expand All @@ -30,7 +34,7 @@ def get_T_depth_wire(cpt_circuit: AbstractCircuit):
opstr = str(operator)
if opstr[0] == 'T':
reg_label = opstr[opstr.find("(")+1:opstr.find(")")]
if not reg_label in count_dict:
if reg_label not in count_dict:
count_dict[reg_label] = 1
else:
count_dict[reg_label] += 1
Expand Down Expand Up @@ -87,7 +91,8 @@ def get_T_depth(cpt_circuit: AbstractCircuit):
def gen_resource_estimate(cpt_circuit: AbstractCircuit,
is_extrapolated: bool,
total_steps:int = -1,
circ_occurences:int = -1) -> dict:
circ_occurences:int = -1,
bits_precision:int=1) -> dict:
'''
Given some clifford + T circuit and a given filename, we grab the logical resource estimates
from the circuit and then write it to disk. The function also returns the resource dictionary
Expand Down Expand Up @@ -115,12 +120,19 @@ def gen_resource_estimate(cpt_circuit: AbstractCircuit,
}

if total_steps > 0 and is_extrapolated:
resource_estimate['t_depth'] = resource_estimate['t_depth'] * total_steps
resource_estimate['t_count'] = resource_estimate['t_count'] * total_steps
resource_estimate['max_t_depth_wire'] = resource_estimate['max_t_depth_wire'] * total_steps
resource_estimate['gate_count'] = resource_estimate['gate_count'] * total_steps
resource_estimate['circuit_depth'] = resource_estimate['circuit_depth'] * total_steps
resource_estimate['clifford_count'] = resource_estimate['clifford_count'] * total_steps
scaling_factor = total_steps
elif bits_precision > 0:
scaling_factor = pow(2, bits_precision - 1)
else:
scaling_factor = None

if scaling_factor:
resource_estimate['t_depth'] = resource_estimate['t_depth'] * scaling_factor
resource_estimate['t_count'] = resource_estimate['t_count'] * scaling_factor
resource_estimate['max_t_depth_wire'] = resource_estimate['max_t_depth_wire'] * scaling_factor
resource_estimate['gate_count'] = resource_estimate['gate_count'] * scaling_factor
resource_estimate['circuit_depth'] = resource_estimate['circuit_depth'] * scaling_factor
resource_estimate['clifford_count'] = resource_estimate['clifford_count'] * scaling_factor

if circ_occurences > 0:
resource_estimate['subcicruit_occurrences'] = circ_occurences
Expand Down Expand Up @@ -168,12 +180,13 @@ def circuit_estimate(
numsteps: int,
circuit_name: str,
algo_name:str,
bits_precision:int=1,
write_circuits:bool = False
) -> AbstractCircuit:
if not os.path.exists(outdir):
os.makedirs(outdir)
subcircuit_counts = dict()

subcircuit_counts = {}
for moment in circuit:
for operation in moment:
gate_type = type(operation.gate)
Expand Down Expand Up @@ -213,7 +226,8 @@ def circuit_estimate(
subcircuit_name = subcircuit_counts[gate][2]
resource_estimate = gen_resource_estimate(subcircuit,
is_extrapolated=False,
circ_occurences=subcircuit_counts[gate][0])
circ_occurences=subcircuit_counts[gate][0],
bits_precision=bits_precision)
subcircuit_info = {subcircuit_name:resource_estimate}
subcircuit_re.append(subcircuit_info)

Expand All @@ -230,6 +244,13 @@ def circuit_estimate(
total_T_depth_wire += subcircuit_counts[gate][0] * t_depth_wire * numsteps
total_T_count += subcircuit_counts[gate][0] * t_count * numsteps
total_clifford_count += subcircuit_counts[gate][0] * clifford_count * numsteps

# total_gate_count += subcircuit_counts[gate][0] * gate_count * numsteps * pow(2, bits_precision - 1)
# total_gate_depth += subcircuit_counts[gate][0] * gate_depth * numsteps * pow(2, bits_precision - 1)
# total_T_depth += subcircuit_counts[gate][0] * t_depth * numsteps * pow(2, bits_precision - 1)
# total_T_depth_wire += subcircuit_counts[gate][0] * t_depth_wire * numsteps * pow(2, bits_precision - 1)
# total_T_count += subcircuit_counts[gate][0] * t_count * numsteps * pow(2, bits_precision - 1)
# total_clifford_count += subcircuit_counts[gate][0] * clifford_count * numsteps * pow(2, bits_precision - 1)

outfile_data = f'{outdir}{circuit_name}_high_level.json'
total_resources = {
Expand Down Expand Up @@ -268,4 +289,4 @@ def re_as_json(main_estimate:dict, estimates:list[dict], file_name:str, algo_nam
with open(file_name, 'w') as f:
json.dump(main_estimate, f,
indent=4,
separators=(',', ': '))
separators=(',', ': '))
Loading