BoltzmannEntropy commited on
Commit
41e6c53
·
1 Parent(s): 334036d
Files changed (2) hide show
  1. Dockerfile +1 -1
  2. app.py +48 -38
Dockerfile CHANGED
@@ -85,7 +85,7 @@ COPY --chown=user:user app.py .
85
  # COPY --chown=user:user test_images /home/user/app/test_images
86
 
87
  ENV PYTHONUNBUFFERED=1 GRADIO_ALLOW_FLAGGING=never GRADIO_NUM_PORTS=1 GRADIO_SERVER_NAME=0.0.0.0 GRADIO_SERVER_PORT=7860 SYSTEM=spaces
88
- RUN python3 -m pip install pennylane sympy pennylane-qiskit duckdb
89
  WORKDIR $HOME/app
90
 
91
  EXPOSE 8097 7842 8501 8000 6666 7860
 
85
  # COPY --chown=user:user test_images /home/user/app/test_images
86
 
87
  ENV PYTHONUNBUFFERED=1 GRADIO_ALLOW_FLAGGING=never GRADIO_NUM_PORTS=1 GRADIO_SERVER_NAME=0.0.0.0 GRADIO_SERVER_PORT=7860 SYSTEM=spaces
88
+ RUN python3 -m pip install pennylane sympy pennylane-qiskit duckdb qutip qutip-qip
89
  WORKDIR $HOME/app
90
 
91
  EXPOSE 8097 7842 8501 8000 6666 7860
app.py CHANGED
@@ -10,33 +10,20 @@ import matplotlib.pyplot as plt
10
  from PIL import Image
11
  import pennylane as qml
12
  import base64
13
-
14
- from numpy import pi
15
- import numpy as np
16
  from qutip import *
17
  from qutip.qip.operations import *
18
  from qutip.qip.circuit import QubitCircuit, Gate
 
 
19
 
20
- # Define a device
21
  dev = qml.device('default.qubit', wires=10)
22
 
23
- def plot_qutip_circuit():
24
- q = QubitCircuit(2, reverse_states=False)
25
- q.add_gate("CNOT", controls=[0], targets=[1])
26
-
27
- # Display the circuit as an image
28
- q.png # Generates and renders the circuit diagram
29
-
30
- return q
31
-
32
-
33
  # Hugging Face and DuckDB function placeholders
34
  def store_in_hf_dataset(data):
35
- # Implement storing data in the Hugging Face dataset
36
  pass
37
 
38
  def load_from_hf_dataset():
39
- # Implement loading data from the Hugging Face dataset
40
  return []
41
 
42
  # Function to buffer the plot and return as PIL image
@@ -52,6 +39,13 @@ def pil_image_to_bytes(image):
52
  image.save(img_byte_arr, format='PNG')
53
  return img_byte_arr.getvalue()
54
 
 
 
 
 
 
 
 
55
  # Function to generate a random Hamiltonian
56
  def generate_random_hamiltonian(num_qubits):
57
  terms = []
@@ -88,20 +82,24 @@ def hamiltonian_to_qasm(hamiltonian, num_qubits):
88
 
89
  return qasm_code
90
 
91
- # Function for Trotter decomposition
92
- def trotter_decomposition(hamiltonian, order):
93
- terms = hamiltonian.split(" + ")
94
- trotter_steps = []
95
 
96
- for term in terms:
97
- coeff, *pauli_ops = term.split(" * ")
98
- coeff = float(coeff)
99
- for _ in range(order):
100
- trotter_steps.append(f"exp({coeff / order}) * ({' * '.join(pauli_ops)})")
101
- for _ in range(order):
102
- trotter_steps.append(f"exp({-coeff / order}) * ({' * '.join(pauli_ops)})")
 
 
 
 
103
 
104
- return " + ".join(trotter_steps)
105
 
106
  # Store data in DuckDB
107
  def store_in_duckdb(data, db_file='quantum_hamiltonians.duckdb'):
@@ -120,13 +118,7 @@ def store_in_duckdb(data, db_file='quantum_hamiltonians.duckdb'):
120
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)""", data)
121
  conn.close()
122
 
123
- # Load results from DuckDB and encode images to base64
124
- def encode_image_from_blob(blob):
125
- img_buffer = io.BytesIO(blob)
126
- image = Image.open(img_buffer)
127
- img_str = base64.b64encode(img_buffer.getvalue()).decode("utf-8")
128
- return f'<img src="data:image/png;base64,{img_str}" style="max-width:500px;"/>'
129
-
130
  def load_from_duckdb(db_file='quantum_hamiltonians.duckdb'):
131
  conn = duckdb.connect(database=db_file)
132
  df = conn.execute("SELECT * FROM hamiltonians").df()
@@ -185,9 +177,11 @@ def generate_hamiltonians(num_hamiltonians, selected_qubits, selected_order, wri
185
  qasm_code = hamiltonian_to_qasm(hamiltonian, num_qubits)
186
  trotter_code = trotter_decomposition(hamiltonian, order)
187
 
188
- # Create a dummy plot (replace with actual plot creation logic)
189
- fig, ax = plt.subplots()
190
- ax.plot([0, 1], [0, 1])
 
 
191
  circuit_plot_image = buffer_plot_and_get(fig)
192
  circuit_plot_bytes = pil_image_to_bytes(circuit_plot_image)
193
 
@@ -209,6 +203,22 @@ def load_results(load_from_hf, load_from_duckdb1):
209
  if load_from_duckdb1:
210
  return load_from_duckdb()
211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  # Gradio app
213
  with gr.Blocks() as app:
214
  gr.Markdown("# Quantum Hamiltonian Generator")
 
10
  from PIL import Image
11
  import pennylane as qml
12
  import base64
 
 
 
13
  from qutip import *
14
  from qutip.qip.operations import *
15
  from qutip.qip.circuit import QubitCircuit, Gate
16
+ import pennylane as qml
17
+ from math import pi
18
 
19
+ # Define a Pennylane device
20
  dev = qml.device('default.qubit', wires=10)
21
 
 
 
 
 
 
 
 
 
 
 
22
  # Hugging Face and DuckDB function placeholders
23
  def store_in_hf_dataset(data):
 
24
  pass
25
 
26
  def load_from_hf_dataset():
 
27
  return []
28
 
29
  # Function to buffer the plot and return as PIL image
 
39
  image.save(img_byte_arr, format='PNG')
40
  return img_byte_arr.getvalue()
41
 
42
+ # Encode the image in base64 to display in HTML
43
+ def encode_image_from_blob(blob):
44
+ img_buffer = io.BytesIO(blob)
45
+ image = Image.open(img_buffer)
46
+ img_str = base64.b64encode(img_buffer.getvalue()).decode("utf-8")
47
+ return f'<img src="data:image/png;base64,{img_str}" style="max-width:500px;"/>'
48
+
49
  # Function to generate a random Hamiltonian
50
  def generate_random_hamiltonian(num_qubits):
51
  terms = []
 
82
 
83
  return qasm_code
84
 
85
+ # Function to parse QASM code and create Pennylane circuit
86
+ def qasm_to_pennylane(qasm_code):
87
+ qasm_lines = qasm_code.split("\n")
88
+ num_qubits = int(qasm_lines[2].split('[')[1].split(']')[0]) # Extract number of qubits from QASM
89
 
90
+ @qml.qnode(dev)
91
+ def circuit():
92
+ for line in qasm_lines:
93
+ if "x" in line:
94
+ qml.PauliX(int(line.split('q[')[1].split(']')[0]))
95
+ elif "rz" in line:
96
+ angle = float(line.split('(')[1].split(')')[0])
97
+ qml.RZ(angle, int(line.split('q[')[1].split(']')[0]))
98
+ elif "ry" in line:
99
+ qml.RY(pi / 2, int(line.split('q[')[1].split(']')[0]))
100
+ return qml.state()
101
 
102
+ return circuit
103
 
104
  # Store data in DuckDB
105
  def store_in_duckdb(data, db_file='quantum_hamiltonians.duckdb'):
 
118
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)""", data)
119
  conn.close()
120
 
121
+ # Function to load results from DuckDB
 
 
 
 
 
 
122
  def load_from_duckdb(db_file='quantum_hamiltonians.duckdb'):
123
  conn = duckdb.connect(database=db_file)
124
  df = conn.execute("SELECT * FROM hamiltonians").df()
 
177
  qasm_code = hamiltonian_to_qasm(hamiltonian, num_qubits)
178
  trotter_code = trotter_decomposition(hamiltonian, order)
179
 
180
+ # Generate Pennylane circuit from QASM code
181
+ circuit = qasm_to_pennylane(qasm_code)
182
+
183
+ # Draw the Pennylane circuit and save as an image
184
+ fig, ax = qml.draw_mpl(circuit)()
185
  circuit_plot_image = buffer_plot_and_get(fig)
186
  circuit_plot_bytes = pil_image_to_bytes(circuit_plot_image)
187
 
 
203
  if load_from_duckdb1:
204
  return load_from_duckdb()
205
 
206
+ # Function for Trotter decomposition
207
+ def trotter_decomposition(hamiltonian, order):
208
+ terms = hamiltonian.split(" + ")
209
+ trotter_steps = []
210
+
211
+ for term in terms:
212
+ coeff, *pauli_ops = term.split(" * ")
213
+ coeff = float(coeff)
214
+ for _ in range(order):
215
+ trotter_steps.append(f"exp({coeff / order}) * ({' * '.join(pauli_ops)})")
216
+ for _ in range(order):
217
+ trotter_steps.append(f"exp({-coeff / order}) * ({' * '.join(pauli_ops)})")
218
+
219
+ return " + ".join(trotter_steps)
220
+
221
+
222
  # Gradio app
223
  with gr.Blocks() as app:
224
  gr.Markdown("# Quantum Hamiltonian Generator")