-
Notifications
You must be signed in to change notification settings - Fork 4
GA‐QAS: Introduction
In various quantum optimization problems, choosing the right ansatz is a critical point that will affect the result. Many template ansatzes have been proposed, such as Graph Ansatz and EffecientSU2, … but they are limited to the applications that you can apply. Then, we propose a search engine called GA-QAS (Genetic algorithm for quantum architecture search). This search engine can take your problem as input and return a good ansatz for you. In this post, we will guide you on how to use it efficiently.

Fig 1. State preparation scheme based on quantum compilation technique, where
In this post, we will use a Python package named
!git clone https://github.com/vutuanhai237/qoop.git
Note that you should put it on the same level as your Python/Jupyter Notebook file. The best is:
folder_name
│ your_python_file.py
| your_jupyter_file.ipynb
└───qoop
│ └───evolution
│ │ environment.py
│ │ cross_over.py
│ │ ...
If not, you should include this line to config the path:
import sys
sys.path.insert(..)
The required packages are qiskit, matplotlib, and tdqm. First, we define the problem, take example quantum state preparation, more easier W state preparation. 3-qubit W state is defined as:
And so on for a larger number of qubits. If we want to prepare such a state, we will need to care about the unitary operator
You can try to prepare 3-qubit W state by using
from qoop.compilation.qsp import QuantumStatePreparation
from qoop.core import ansatz, state
compiler = QuantumStatePreparation(
u = ansatz.g2(num_qubits = 3, num_layers = 1)
target_state = state.w(num_qubits = 3).inverse()
).fit(num_steps = 100) # Define the optimization process and begin to optimize in 100 iterations
compiler.plot() # Plot optimization process
Make sure that you can run the above code. We wrap it into a function
import qiskit
def fitnessW(qc: qiskit.QuantumCircuit):
qsp = QuantumStatePreparation(
u = qc,
target_state = state.w(num_qubits = 3).inverse()
).fit()
return 1 - qsp.compiler.metrics['loss_fubini_study'][-1] # Fitness value

Fig 2. The general pipeline of GA-QAS
A genetic algorithm (GA) is a heuristic algorithm based on a genetic combination process. GA processes include Selection, Cross-over, and Mutation. We treat ansatz as an individual in the population (where gates are its genes).
Process | Method |
---|---|
Population generation | A |
Selection | Get fitness value from the fitness function; simply sort from high to low and take the first half part |
Cross-over | Divide 2 ansatz into four parts, then combine each two parts into 2 new ansatz |
Mutation | Each gate on ansatz has a small probability of mutating to another gate (with the same number of qubits) in the pool |
Tab 1. Detail of each operation in GA-QAS.
The overall process can be viewed in Fig. 2.
In GA, some hyper-parameters need to be considered and defined before you run GA-QAS:
from qoop.evolution.environment import EEnvironmentMetadata
env_metadata = EEnvironmentMetadata(
num_qubits, # As its name
depth, # Ansatz depth you want
num_circuit, # Number of ansatz per generation
num_generation, # Number of generation/iteration for GA
prob_mutate # Mutation probability, usually as small as 0.01 (1%)
)
Then, you need to create an Environment
object, the important parameter is fitness_func
, which is the function name that we declared above:
from qoop.evolution.environment import EEnvironment
env = EEnvironment(
metadata = env_metadata,
fitness_func = fitnessW,
)
The object EEnvironment has other parameters such as selection_func
, crossover_func
, mutate_func
, threshold_func
which can be imported from below sub-module:
from qoop.evolution import crossover, mutate, selection, threshold
or defined by yourself.
Parrameter | Default | Function type |
---|---|---|
selection_func | selection.elitist_selection |
|
crossover_func | crossover.onepoint_crossover |
|
mutate_func | mutate.layerflip_mutate |
|
threshold_func | threshold.compilation_threshold |
|
Table 2: Functions for GA-QAS
You can call the method evol()
to start running GA-QAS.
env.evol(
verbose = 1,
auto_save = True
)
There are only two parameters: the first is verbose (1 means print % process, 0 means no print), and the second is the saving option. The saving result's folder is detailed on GA-QAS: folder result.
Currently, we support plotting fitness values against a number of generations. In the future, we will develop more presentation plots.
env.plot()
Fig 3. Fitness values versus number of generations.
The result is saved in a folder; the default folder name is based on the fitness function name. We care about a file named best_circuit.qpy
, which is our final solution. Then, we can load it by
from qoop.backend import utilities
best_circuit = utilities.load_circuit("Path to best_circuit.qpy")
fitness_value = fitnessW(best_circuit)
In this post, we have introduced a way to use GA-QAS, just define your own problem (fitness function) and it will help you find best ansatz automatically. For more information and documentation, explore the following links:
-
$\langle qo|op\rangle$ : core package for GA-QAS. - GA-QAS:
Thanks for reading! Please do not hesitate to ask us any questions via e-mail: vutuanhai237@gmail.com or LinkedIn.
[1] Hai, V. T., Viet, N. T., & Ho, L. B. (2023). Variational preparation of entangled states on quantum computers. arXiv preprint arXiv:2306.17422.
[2] Khatri, S., LaRose, R., Poremba, A., Cincio, L., Sornborger, A. T., & Coles, P. J. (2019). Quantum-assisted quantum compiling. Quantum, 3, 140.
The Jupyter notebook which contains the above code can be found here
import qiskit
from qoop.core import state, metric, ansatz
from qoop.compilation.qsp import QuantumStatePreparation
from qoop.evolution.environment import EEnvironmentMetadata
from qoop.evolution.environment import EEnvironment
def fitnessW(qc: qiskit.QuantumCircuit):
qsp = QuantumStatePreparation(
u = qc,
target_state = state.w(num_qubits = 3).inverse()
).fit(num_steps = 100)
return 1 - qsp.compiler.metrics['loss_fubini_study'][-1] # Fitness value
env_metadata = EEnvironmentMetadata(
num_qubits = 3, # As its name
depth = 4, # Ansatz depth you want
num_circuit = 4, # Number of ansatz per generation
num_generation = 10, # Number of generation/iteration for GA
prob_mutate = 0.01 # Mutation probability, usually as small as 0.01 (1%)
)
env = EEnvironment(
metadata = env_metadata,
fitness_func = fitnessW,
).evol()
Copyright @ 2024 Hai et al
- Home
- Contribute guideline
- Installation guideline
- Package requirements
- Core
- GA-QAS
- Example
- Advanced